#include "ClientHandler.h"
#include "TLog.h"
#include "ActiveConnsList.h"
#include "StreamPacketBuilder.h"
#include "SqlMemoryPool.h"
#include "DataBaseThread.h"
#include "GameMemoryPool.h"
#include "RoomManager.h"
#include "PrivateTableManager.h"
#include "NormalTable.h"
#include "RouletteManager.h"
#include "SlotManager.h"
#include "CommodityManager.h"
#include "TaskManager.h"
#include "../ip_database/TIPDataBase.h"
#include "SysError.h"
#include "des.h"
#include "CsvDataMgr.h"
#include "json/json.h"
#include "GameLotteryMgr.h"
#include "Config.h"
#include "GoodCardManager.h"
#include "CBrcMsgHandle.h"
#include "GameLotteryNew.h"
#include "Lianghao.h"
#include "HongbaoLogic.h"
#include "stdlib.h"
#include <stdexcept>

//充值定义
#define PAY_TYPE_ZFB		101		//支付宝
#define PAY_TYPE_YHK		102		//银行卡
#define PAY_TYPE_XYK		103		//信用卡
#define PAY_TYPE_DX			106		//短信充值
#define PAY_TYPE_SJK		109		//手机卡
#define PAY_TYPE_WX			110		//微信支付
#define PAY_TYPE_OTHER		120		//其它充值方式

bool HttpHandler::handle_read( TEventHandler * object ){
	m_active_time = time(NULL);
	while ( this->m_wait_read_byte > 0 ){
		int remain  = HTTP_SOCKET_BUFFER_LEN - m_recv_byte ;
		if ( remain <= 0 ) 
		{
			m_recv_byte = 0 ; 
			return false ;
		}
		int rc		= read( this->get_handle() , m_buffer + m_recv_byte, remain );
		if ( rc <= 0 ) {
			if ( errno == EINTR ) continue ;
			WL(LL_ERROR ,"HttpHandler::handle_read error = %d str=%s %d",errno , strerror(errno) , remain );
			m_recv_byte = 0 ;
			return false ;
		}
		m_wait_read_byte		-= rc ;
		m_recv_byte				+= rc ;
		m_content				= strstr( m_buffer , "\r\n\r\n") ;
		if ( m_content != NULL ) //已经把头部收完了
		{
			m_content += 4 ;
			int content_len = get_content_len();

			if ( content_len > 0 )
			{
				int packet_len  = m_content - m_buffer + content_len ;
				//一包接收完了哦
				if ( m_recv_byte >= packet_len )
				{
					commit_packet( content_len );
					m_recv_byte -= packet_len ;
					if ( m_recv_byte > 0 ) memmove( m_buffer , m_buffer + packet_len , m_recv_byte );
				}
			}
			else
			{
				WL(LL_ERROR,"m_recv_byte = %d http=%s content_len = %d\n",m_recv_byte , m_buffer , content_len );
				return false ;
			}
		}

	}
	return true ;
}
int	HttpHandler::get_content_len(){
	char * pos = strstr( m_buffer , "Content-Length: ");
	if( pos == NULL){
		return -1;
	}
	pos += 16;
	return atoi( pos );
}

const char KEY[] = {113, 101, 116, 95, 107, 101, 121, 95};

char * my_strtok1( char * src , char delim , char *& next ){
	if ( src == NULL ) return NULL ;
	char * dst  = src ;
	next		= NULL ;
	while ( *dst != '\0'  ){
		if ( *dst == delim ){
			next = dst + 1 ;
			*dst = '\0';
			break;
		}
		dst ++ ;
	}
	return src  ;
}
bool HttpHandler::commit_packet( int content_len ){

	char decrypted[ 1024*4 ] = { 0 };
	memcpy(decrypted, m_content, content_len);
	//DesDecrypt((unsigned char*)m_content, content_len, (unsigned char*)decrypted, (char*)KEY);

	Json::Reader readerJson;  
	Json::Value valueJson;  
	if (readerJson.parse(decrypted, valueJson) && valueJson["type"].isInt())
	{
		try {
		int typeindex = valueJson["type"].asInt();  

		g_pFlowLog->logMsg( "zq content=%s;content_len=%d\n  type:%d",decrypted , content_len ,typeindex);

		if ( typeindex == 0)//充值
		{
			std::string order = valueJson["order"].asString();  

			int money = valueJson["money"].asInt();  
			int payment = valueJson["payment"].asInt();  
			int goodsId = valueJson["goodsId"].asInt();
			int userId = atoi ( valueJson["userId"].asString().c_str() );

			std::string userData = valueJson["userData"].asString();  
			std::string pay_msg = valueJson["msg"].asString();  
			std::string pay_sign = valueJson["sign"].asString();
			int channel = 0;
			channel = valueJson["channel"].asInt();
			if (goodsId == yiyuan_hongbao_goodsid)
			{
				handleCommitYiyuanPayResult(order.c_str(), userId, goodsId, payment, money, pay_msg.c_str(), channel);
			}
			else
			{
				handleCommitPayResult(order.c_str(), userId, goodsId, payment, money, pay_msg.c_str(), channel);
			}
		}
		else if ( typeindex == 1 )//在游戏中给用户加金币
		{
			int userId = valueJson["userId"].asInt();
			INT64  goldnum = valueJson["goldnum"].asInt();
			//INT64  goldnum = ::atoll(valueJson["goldnum"].asString().c_str());
			int diamond = valueJson["diamond"].asInt();
			int deposit = valueJson["deposit"].asInt();
			int type = 0;
			type = valueJson["email_type"].asInt();
			type = (type == 0) ? 2 : type;
			int module_type = 9;
			module_type = valueJson["module_type"].asInt();
			module_type = (module_type == 0) ? 9 : module_type;
			OnHttpModifyGold( userId, goldnum, diamond, deposit ,type, module_type);
		}
		else if ( (typeindex == 2) )//修改账号密码
		{
			std::string telephone = valueJson["tel"].asString();  
			std::string pwd = valueJson["password"].asString();  
			OnHttpResetPwd( (char*)telephone.c_str(), (char*)pwd.c_str(), typeindex );
		}
		else if ( typeindex == 3 )//修改用户头像
		{
			int userId = valueJson["userId"].asInt();
			std::string picstr = valueJson["pic"].asString();
			OnHttpUpdateHeaderPic( userId, (char*)picstr.c_str() );

		}
		else if ( typeindex == 4 )//重新加载配置
		{
			int index = valueJson["index"].asInt();  //参照 RELOAD_CONFIG_TYPE 定义
			OnHttpUpdateCongif( (RELOAD_CONFIG_TYPE)index );
		}
		else if ( typeindex == 5 )//系统维护消息
		{
			DWORD starttime = valueJson["starttime"].asUInt();
			DWORD endtime = valueJson["endtime"].asUInt();
			std::string message = valueJson["message"].asString();
			Config::instance()->set_mantain_time( starttime, endtime, (char*)message.c_str() );
			response_sucessful(NULL);
		}
		else if ( typeindex == 6 )//大喇叭
		{
			std::string content = valueJson["content"].asString();
			StreamPacketBuilder::instance()->notifySystemBroadcast( (u8_t*)content.c_str(), strlen(content.c_str()) ,0);
		}
		else if ( typeindex == 7 )//商品被购买
		{
			//MSG_RSP_SELLGOODS_BUY
			int selluserId = valueJson["sellid"].asInt();
			int buyuserId = valueJson["buyid"].asInt();
			int index = valueJson["index"].asInt();
			string emailcontent = valueJson["email"].asString();
			OnHttpBuyPlayerGoods( index, selluserId, buyuserId, emailcontent );
		}
		else if ( typeindex == 8 )//邀请码
		{
			DWORD userid = valueJson["uid"].asInt();  
			std::string message = valueJson["msg"].asString();  
			OnHttpUpdateWealth( userid, (char*)message.c_str() );
		}
		else if ( typeindex == 9 )//T人下线
		{
			DWORD userid = valueJson["userId"].asInt();  
			OnHttpKickPlayer( userid );
		}
		else if ( typeindex == 10 )//修改vip通知
		{
			DWORD userid = valueJson["userId"].asInt();  
			DWORD viplevel = valueJson["viplevel"].asInt(); 
			DWORD vippoint = valueJson["vippoint"].asInt();
			DWORD cardtype = valueJson["lottery_id"].asInt();
			DWORD cardnum = valueJson["nums"].asInt();
			OnHttpUpdateVepLevel( userid, viplevel,vippoint, cardtype, cardnum );
		}
		else if ( typeindex == 11 )//HTTP֪ͨ
		{
			int color  = 0;
			int nUserId = valueJson["uid"].asInt();
			std::string content = valueJson["content"].asString();
			color = valueJson["color"].asInt();
			//printf( "uid = %d color = %d,content:%s\r\n", nUserId, color ,content.c_str() );
			//StreamPacketBuilder::instance()->handleBroadcast( MSG_NOTIFY_MESSAGE, (u8_t*)content.c_str(), content.length() );
			StreamPacketBuilder::instance()->notifySystemBroadcast( (u8_t*)content.c_str(), strlen(content.c_str()), nUserId , color);
			response_sucessful(NULL);
		}
		else if(typeindex == 12)  //update git ,ticket
		{
			int userId = valueJson["userId"].asInt();
			int giftid = valueJson["gift_id"].asInt();  
			int giftnum = valueJson["gift_num"].asInt();
			int ticket = valueJson["ticket"].asInt();
			std::string content = valueJson["email"].asString();
			OnHttpUdateGift(userId,giftid, giftnum, ticket, content);
		}
		else if(typeindex == 13)
		{
			int nUserID = valueJson["userId"].asInt();
			int nBidID = valueJson["lh_id"].asInt();
			int nPrice = valueJson["gold"].asInt();
			int nJiangpaiCnt = valueJson["jingpai"].asInt();
			int nWeiGuanCnt = valueJson["weiguan"].asInt();
			int second = valueJson["daojishi"].asInt();
			
			LiangHao::instance()->getJoinBidNumPlayers(nUserID, nBidID, nPrice, nWeiGuanCnt,nJiangpaiCnt, second);
		}
		else if(typeindex == 14)
		{
			int nUserID = valueJson["userId"].asInt();
			OnHttpUpdateTexiao(nUserID);
		}
		else if(typeindex == 15) 
		{
			int nUserID = valueJson["userId"].asInt();
			int nEmailType = valueJson["email_type"].asInt();
			string content = valueJson["contents"].asString();

			OnHttpUserEmailNotify(nUserID, content, nEmailType);
			
		}
		else if(typeindex == 16)	//Ò»Ôª¶á±¦Í¨Öª
		{
			int nUserID = valueJson["userId"].asInt();
			string content = valueJson["contents"].asString();

			OnHttpWinningDuobaoNotify(nUserID, content);
		}
		else if(typeindex == 17)
		{
			int userId = valueJson["userId"].asInt();
			INT64  goldnum = ::atoll(valueJson["goldnum"].asString().c_str());
			int diamond = valueJson["diamond"].asInt();
			int deposit = valueJson["deposit"].asInt();
			int type = 0;
			type = valueJson["email_type"].asInt();
			type = (type == 0) ? 2 : type;
			int module_type = 9;
			module_type = valueJson["module_type"].asInt();
			module_type = (module_type == 0) ? 9 : module_type;
			OnHttpModifyGold( userId, goldnum, diamond, deposit ,type, module_type);
		}
		else if (typeindex == 18)
		{
			int notify_type = 0;
			string player_list;
			notify_type = valueJson["notify_type"].asInt();
			if ( notify_type == 0 )
			{
				player_list = valueJson["player_list"].asString();
			}

			string  title = valueJson["title"].asString();
			string  content = valueJson["content"].asString();

			OnHttpPushNotify(notify_type, title, content, player_list);
		}
		}
		catch(const std::runtime_error &e)
		{
			WL(LL_INFO ,"runtime_err HttpHandler parse faild m_content = %s \n", decrypted);			
		}
	}
	else {
		WL(LL_INFO ,"HttpHandler parse faild m_content = %s \n", decrypted);
	}
	return true ;
}
void HttpHandler::response_sucessful( Player * player   ){
	char content [ 250 ] = { 0 };
	StreamWriter stream_writer( content );
	//stream_writer.add_byte( RESULT_OK );
	//stream_writer.add_byte( 11 );

	char str_response [ 120 ] = { 0 };
	snprintf( str_response , sizeof(str_response) ,"{\"status\":%d}", RESULT_OK ) ;
	stream_writer.appand( str_response );
	stream_writer.add_byte('\0');
	//printf( "str_response:%s\r\n", str_response );
	//StreamPacketBuilder::instance()->writeUserInfo( stream_writer , player );
	char str_content_len [ 20 ] = { 0 };
	snprintf( str_content_len , sizeof(str_content_len) ,"%d", stream_writer.get_buffer_len() ) ;

	StreamWriter writer( m_buffer );
	writer.appand("HTTP/1.1 200 OK\r\n");
	writer.appand("Content-Length: ");
	writer.appand( str_content_len );
	writer.appand( "\r\n", 2 ); 
	writer.appand("Connection: close\r\n\r\n");
	writer.appand( content , stream_writer.get_buffer_len() );
	safe_send( writer.get_buffer() , writer.get_buffer_len() );
	shutdown( get_handle() , SHUT_RDWR );
}
void HttpHandler::response_faild( int err_number , const char * err  ){
	char content [ 250 ] = { 0 };
	StreamWriter stream_writer( content );
	
	char str_response [ 120 ] = { 0 };
	snprintf( str_response , sizeof(str_response) ,"{\"status\":%d}", err_number ) ;
	stream_writer.appand( str_response );
	stream_writer.add_byte('\0');
	//printf( "str_response:%s\r\n", str_response );
	char str_content_len [ 20 ] = { 0 };
	snprintf( str_content_len , sizeof(str_content_len) ,"%d", stream_writer.get_buffer_len()) ;

	StreamWriter writer( m_buffer );
	writer.appand("HTTP/1.1 200 OK\r\n");
	writer.appand("Content-Length: ");
	writer.appand( str_content_len );
	writer.appand( "\r\n", 2 );
	writer.appand("Connection: close\r\n\r\n");
	writer.appand( content , stream_writer.get_buffer_len() );
	safe_send( writer.get_buffer() , writer.get_buffer_len() );
	shutdown( get_handle() , SHUT_RDWR );

}
int  HttpHandler::safe_send( const char * data , const int len ){
	int rc = 0 ;
	while ( ( rc = write( this->get_handle() , data ,len )) <=0 )
	{
		if ( errno == EINTR ) continue;
		break;
	}
	return rc ;
}
void HttpHandler::handle_close( TEventHandler * object ){
	HttpLisentor::instance()->freeObj( object );
}

void HttpHandler::procDataBaseReturn( SQLResp * resp )
{
	//printf( "zq resp->req_type = %d REQ_TYPE_HTTP_RESET_PWD = %d\r\n", resp->req_type, REQ_TYPE_HTTP_RESET_PWD ) ;
	if ( resp->req_type == REQ_TYPE_FINISH_PAY_RESULT )
	{
		handlePayResult( resp );
	}
	else if (resp->req_type == REQ_TYPE_CLIENT_COMMIT_CHARGE_RESULT) {
		handleChargeResult( resp );
	}
	else if ( resp->req_type == REQ_TYPE_UPDATE_GOLD )
	{
		OnDBModyfyGold( resp );
	}
	else if ( resp->req_type == REQ_TYPE_HTTP_RESET_PWD )
	{
		//printf( "zq OnDBResult=========\r\n" );
		OnDBResult( resp );
	}

	else if(resp->req_type == REQ_TYPE_UPDATE_GIFT_CNT)
	{
		OnDBModifyGift(resp);
	}
	else if (resp->req_type == REQ_TYPE_FINISH_PAY_YIYUAN_RESLUT)
	{
		handleYiyuanPayResult(resp);
	}
}

void HttpHandler::handleCommitPayResult(const char * pOrder, int userId, int goodsId, int payment, int money, const char * pErrMsg,int channel)
{
	if (pErrMsg == NULL)
		return;
	//v_pOrder v_userId v_goodsId v_payment v_money v_status
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_FINISH_PAY_RESULT , this );
	int paystatus = 1;	//
	char errMsg[128] = {0};
	req->id = 0;
	if ( payment == PAY_TYPE_SJK )
	{
		int errmsgid = atoi( pErrMsg );
		if ( errmsgid != 0 )
		{
			paystatus = 0;
		}
		strcat( errMsg, (char*)getPayErrorString( pErrMsg).c_str() ); 
	}
	char desBuff[128] = {0};
	CsvDataMgr::instance()->gb2312toutf8((char *)errMsg, strlen(errMsg), desBuff, sizeof(desBuff));
	snprintf( req->sql , sizeof(req->sql) ,"call sp_finish_pay('%s', %d, %d, %d, %d, %d, '%s', %d)",pOrder , userId , goodsId, payment, money, paystatus, desBuff ,channel);
	//printf( "zq handleCommitPayResult req->sql:%s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}


void HttpHandler::handleCommitYiyuanPayResult(const char * pOrder,int userId,int goodsId,int payment,int money,const char * pErrMsg,int channel)
{
	if (pErrMsg == NULL)
		return;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_FINISH_PAY_YIYUAN_RESLUT , this );
	int paystatus = 1;	//
	char errMsg[128] = {0};
	req->id = 0;
	if ( payment == PAY_TYPE_SJK )
	{
		int errmsgid = atoi( pErrMsg );
		if ( errmsgid != 0 )
		{
			paystatus = 0;
		}
		strcat( errMsg, (char*)getPayErrorString( pErrMsg).c_str() ); 
	}
	char desBuff[128] = {0};
	CsvDataMgr::instance()->gb2312toutf8((char *)errMsg, strlen(errMsg), desBuff, sizeof(desBuff));
	
	snprintf( req->sql , sizeof(req->sql) ,"call sp_finish_pay_yiyuan('%s', %d, %d, %d, %d, %d, '%s', %d)",pOrder , userId , goodsId, payment, money, paystatus, desBuff ,channel);
	DataBaseReadThreadPool::instance()->pushQueue( req );
	printf( "zq handleCommitPayResult req->sql:%s\r\n", req->sql );
}
void HttpHandler::handleCommitChargeResult( BYTE charge_type ,const char * charge_id , BYTE	status ,BYTE order_type )
{
	if ( status == 2 ) return ; //不提交
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_CLIENT_COMMIT_CHARGE_RESULT , this );
	req->id = 0;
	snprintf( req->sql , sizeof(req->sql) ,"call sp_finish_charge_order_type('%s',%d,%d,%d)",charge_id , charge_type , status,order_type );
	//WL(LL_DEV,"sql=%s\n",req->sql);
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void HttpHandler::handleChargeResult( SQLResp * resp )
{
	ChargeResult * r = ( ChargeResult *)resp->data ;
	if ( !resp->result  ) 
	{
		//WL(LL_INFO , "order_id=%s;charge_type=%d;status=%d;errms=%s;order_type=%d\n",order_id , charge_type , status , errmsg,order_type );
		response_faild( ERR_SYSTEM, SysError::instance()->get_errmsg( ERR_SYSTEM ) );
		return ;
	}
	switch ( r->charge_status )
	{
	case CHARGE_STATUS_FAILD:
		WL(LL_WARNING,"charge_id = %s charge faild gold = %u status = %d\n",r->charge_id , r->gold , r->status ) ;
		response_faild( ERR_CHARGE_RECORD , SysError::instance()->get_errmsg( ERR_CHARGE_RECORD ) );
		return;
	case CHARGE_STATUS_NOT_FOUND_ORDER:
		WL(LL_WARNING,"charge_id = %s not found gold = %u\n",r->charge_id , r->gold  ) ;
		response_faild( ERR_CHARGE_NOT_FOUND_ORDER , SysError::instance()->get_errmsg( ERR_CHARGE_NOT_FOUND_ORDER ) );
		return;
	case CHARGE_STATUS_REPEAT_FAILD:
		WL(LL_WARNING,"charge_id = %s repeat notify and deal with faild gold = %u\n",r->charge_id , r->gold  ) ;
		response_faild( ERR_CHARGE_REPEAT_FAILD , SysError::instance()->get_errmsg( ERR_CHARGE_REPEAT_FAILD ) );
		return;
	case CHARGE_STATUS_REPEAT_SUCC:
		WL(LL_WARNING,"charge_id = %s repeat notify  and deal with ok gold = %u\n",r->charge_id , r->gold  ) ;
		//return;
	case CHARGE_STATUS_NOT_FOUND_PROD:
		WL(LL_WARNING,"charge_id = %s not found prop gold = %u\n",r->charge_id , r->gold ) ;
		response_faild( ERR_CHARGE_NOT_FOUND_PROD , SysError::instance()->get_errmsg( ERR_CHARGE_NOT_FOUND_PROD ) );
		return;
	case CHARGE_STATUS_SUCESSFUL:

		//是道具类型的
		if ( r->prod_type == COMMODITY_TYPE_PROP ){
			WL(LL_INFO,"charge_id = %s prod_type=%d prop_id = %d prop_count = %d ticket=%d\n",
				r->charge_id ,r->prod_type, r->prop_id , r->prop_count ,r->ticket_count ) ;
		}else{
			WL(LL_INFO,"charge_id = %s prod_type=%d exchange_gold = %d ticket=%d\n",
				r->charge_id , r->prod_type ,r->gold ,r->ticket_count ) ;
		}
	}
	FrontClientHandler * handler = ActiveConnsList::instance()->find( r->user_id );
	
	if ( handler && handler->getPlayer()  )
	{
		Player * player = handler->getPlayer() ;
		//是道具类型的
		if ( r->prod_type == COMMODITY_TYPE_PROP ) {
			player->set_prop_count( r->prop_id , player->get_prop_count( r->prop_id ) + r->prop_count );
		}
		else{
			player->add_user_gold( r->gold );
		}
		if ( r->present_prop > 0 )
		{
			player->set_prop_count( BROADCAST_PROD_ID , player->get_prop_count( BROADCAST_PROD_ID ) + r->present_prop );
		}

		player->add_user_ticket( r->ticket_count );
		response_sucessful( player );
	}
}

void HttpHandler::handlePayResult( SQLResp * resp )
{
	PayFinishResult * pResult = ( PayFinishResult *)resp->data ;
	FrontClientHandler * handler = ActiveConnsList::instance()->find( pResult->userid );

	response_sucessful( NULL );
	if ( handler && handler->getPlayer()  )
	{
		Player * player = handler->getPlayer() ;
		UserInfo & refuser = player->getUserInfo();
		refuser.user_score.diamond += pResult->diamondnum;
		refuser.user_score.gold += pResult->goldnum;
		int payresult = 1;
		if ( pResult->result_num != 1 )
		{
			payresult = 0;
		}
		else
		{
			//充值成功更新vip和vip到期时间
			refuser.viplevel = pResult->viplevel;
			refuser.vipovertime = pResult->vipovertime;
			refuser.user_score.ticket += pResult->ticket;
			player->set_lotterydraw_count( player->get_lotterydraw_count() + pResult->lotterydrawcount );

		}
		char msgata[512];
		StreamWriter stream_out(msgata,sizeof(msgata));
		stream_out.add_byte( payresult );
		stream_out.add_int( pResult->goodsid );
		stream_out.add_uint( refuser.user_score.diamond );
		stream_out.add_int64( refuser.user_score.gold );
		stream_out.add_byte( refuser.viplevel );
		stream_out.add_uint( refuser.vipovertime );
		stream_out.add_int( pResult->goldnum );	//增加的金币数
		stream_out.add_int( pResult->lotterydrawcount );
		stream_out.add_int( pResult->ticket );	//增加兑奖券
		stream_out.add_int(0);
		handler->sendPacket( MSG_RESP_PAY_FINISH_RESULT, msgata , stream_out.get_buffer_len() );

		//printf( "pResult->result_num =%d\r\n", pResult->result_num  );
		//-1是重复处理订单
		if ( pResult->result_num != -1)
		{
			char senddata[1024] = {0};
			StreamWriter mail_stream_out(senddata, sizeof(senddata));
			mail_stream_out.add_byte( EMAIL_TYPE_PAY);
			int msglen = strlen(pResult->errmsg);
			mail_stream_out.add_short(msglen);
			mail_stream_out.appand(pResult->errmsg, msglen);
			handler->sendPacket(MSG_NOTIFY_ADD_EMAIL, senddata, mail_stream_out.get_buffer_len());
		}
		//通知给桌上上的人用户金币发生改变
		StreamPacketBuilder::instance()->notifyUpdatePlayerGold( player->getTable() , player ) ;; //通知更新金币  
		//printf( "zq **handlePayResult==== pResult->money = %d notifygold : %d\r\n", pResult->money,  Config::instance()->get_send_horn_min_gold(MIN_GOLD_TYPE_PAY) );
		if( pResult->money >= Config::instance()->get_send_horn_min_gold(MIN_GOLD_TYPE_PAY) )
		{
			char szbuff[512] = {0};
			const char *contentformat = Config::instance()->get_horn_format( HORN_FORMAT_PAY );
			if ( contentformat )
			{
				char sendstr[128] = {0};
				char *pStartStr = strchr( (char*)contentformat, (int)'<' );
				char *pEndStr = strchr( (char*)contentformat, (int)'>' );
				if ( !pStartStr || !pEndStr )
				{
					return;
				}	 
				memcpy( sendstr, contentformat, pStartStr - contentformat );
				snprintf(szbuff, sizeof(szbuff), sendstr, handler->getPlayer()->get_nick_name(), pResult->money/100 );
				if ( pResult->goldnum > 0 )
				{
					char tempstr[64] = {0};
					memset( sendstr, 0, sizeof(sendstr) );
					memcpy( sendstr, pStartStr + 1, pEndStr - pStartStr - 1 );
					snprintf(tempstr, sizeof(tempstr), sendstr, pResult->goldnum );
					strcat( szbuff, tempstr );
				}
				pStartStr = strchr( (char*)pEndStr + 1, (int)'<' );
				pEndStr = strchr( (char*)pStartStr, (int)'>' );
				if ( !pStartStr || !pEndStr )
				{
					return;
				}	 
				if ( pResult->diamondnum > 0 )
				{
					char tempstr[64] = {0};
					memset( sendstr, 0, sizeof(sendstr) );
					memcpy( sendstr, pStartStr + 1, pEndStr - pStartStr - 1 );
					snprintf(tempstr, sizeof(tempstr), sendstr, pResult->diamondnum );
					strcat( szbuff, tempstr );
				}
				pStartStr = strchr( (char*)pEndStr + 1, (int)'<' );
				pEndStr = strchr( (char*)pStartStr, (int)'>' );
				if ( !pStartStr || !pEndStr )
				{
					return;
				}	 
				if ( pResult->ticket > 0 )
				{
					char tempstr[64] = {0};
					memset( sendstr, 0, sizeof(sendstr) );
					memcpy( sendstr, pStartStr + 1, pEndStr - pStartStr - 1 );
					snprintf(tempstr, sizeof(tempstr), sendstr, pResult->ticket );
					strcat( szbuff, tempstr );
				}
				StreamPacketBuilder::instance()->notifySystemBroadcast((u8_t *)szbuff, strlen(szbuff)+1, player->get_user_id());
			}
			//snprintf(szbuff, sizeof(szbuff), "恭喜玩家【%s】充值%d元获得了%d金币。", handler->getPlayer()->get_nick_name(), pResult->money/100, pResult->goldnum );		
		}
	}
}


void HttpHandler::handleYiyuanPayResult(SQLResp * resp)
{
	response_sucessful( NULL );
	YiyuanPayFinishResult * pResult = ( YiyuanPayFinishResult *)resp->data ;
	HongbaoLogic::instance()->rechage_callback_notify(pResult->result_num, pResult->userid);
	
}

std::string	HttpHandler::getPayErrorString(const char * pErrorMsg)
{
	if (pErrorMsg == NULL)
		return "";

	int err_code = atoi(pErrorMsg);

	std::string retmsg;
	switch (err_code)
	{
	case 0: retmsg = "销卡成功，订单成功"; break;
	case 1: retmsg = "销卡成功，订单失败"; break;
	case 7: retmsg = "卡号卡密或卡面额不符合规则"; break;
	case 1002: retmsg = "本张卡密您提交过于频繁，请您稍后再试"; break;
	case 1003: retmsg = "不支持的卡类型（比如电信地方卡）"; break;
	case 1004: retmsg = "密码错误或充值卡无效"; break;
	case 1006: retmsg = "充值卡无效"; break;
	case 1007: retmsg = "卡内余额不足"; break;
	case 1008: retmsg = "余额卡过期（有效期1 个月）"; break;
	case 1010: retmsg = "此卡正在处理中"; break;
	case 10000: retmsg = "未知错误"; break;
	case 2005: retmsg = "此卡已使用"; break;
	case 2006: retmsg = "卡密在系统处理中"; break;
	case 2007: retmsg = "该卡为假卡"; break;
	case 2008: retmsg = "该卡种正在维护"; break;
	case 2009: retmsg = "浙江省移动维护"; break;
	case 2010: retmsg = "江苏省移动维护"; break;
	case 2011: retmsg = "福建省移动维护"; break;
	case 2012: retmsg = "辽宁省移动维护"; break;
	case 3001: retmsg = "卡不存在"; break;
	case 3002: retmsg = "卡已使用过"; break;
	case 3003: retmsg = "卡已作废"; break;
	case 3004: retmsg = "卡已冻结"; break;
	case 3005: retmsg = "卡未激活"; break;
	case 3006: retmsg = "密码不正确"; break;
	case 3007: retmsg = "卡正在处理中"; break;
	case 3101: retmsg = "系统错误"; break;
	case 3102: retmsg = "卡已过期"; break;
	default:
		break;
	}

	return retmsg;
}

void PipeEventHandler::handle_close( TEventHandler * object )
{

}

bool PipeEventHandler::init(){
	int fds[2];
	if (pipe(fds)) 
	{
		perror("Can't create notify pipe");
		exit(1);
	}

	m_recv_fd = fds[0];
	m_send_fd = fds[1];
	//printf("init send_fd = %d\n",m_send_fd  );
	this->set_handle( m_recv_fd );
	return true ;
}

void PipeEventHandler::push_queue( SQLResp * resp )
{
	TAutoLock autolock(&m_mutex);
	m_queue.push( resp );
	if (write(m_send_fd, "", 1) != 1) 
	{
		//perror("Writing to  notify pipe");
		printf(" send_fd = %d errno = %d\n",m_send_fd , errno );
	}
}

SQLResp  * PipeEventHandler::get_queue(){
	char		buf[1];

	if (read( m_recv_fd, buf, 1) != 1)
		perror("read to pipe TSqlParser");

	TAutoLock			autolock(&m_mutex);
	SQLResp * resp		= m_queue.front();
	m_queue.pop();
	return resp ;
}

//网络有数据可读时产生该事件
bool PipeEventHandler::handle_read( TEventHandler * object )
{
	while ( m_wait_read_byte > 0 )
	{
		m_wait_read_byte -- ;
		char buf[ 1 ] = { 0 };
		if ( read( m_recv_fd, buf, 1) != 1)
			perror("read to pipe ");
		SQLResp * resp = NULL ;
		m_mutex.lock();
		if ( m_queue.size() > 0 )   {
			resp = m_queue.front();
			m_queue.pop();
		}
		m_mutex.unlock();
		if ( resp != NULL )
		{
			//printf( "zq = handle_read %d \r\n",  resp->req_type );
			if ( resp->req_type >= REQ_TYPE_HTTP_RESET_PWD && resp->req_type < REQ_TYPE_BRC_XZ )
			{
				HttpHandler * handler = static_cast<HttpHandler * >(resp->client); 
				if ( handler )
				{
					handler->procDataBaseReturn( resp );
				}
			}
			else
			{
				FrontClientHandler * handler = static_cast<FrontClientHandler * >(resp->client); 
				if ( handler )
				{
					handler->procDataBaseReturn( resp );
				}
			}
			
			SQLMemoryPool::instance()->freeResp( resp );
			
		}
		//WL(LL_DEBUG ,"net_buffer is null ");
	}
	return true ;
}

FrontClientHandler::FrontClientHandler()
	:m_player(NULL)
{
	memset(&m_localInfo,0,sizeof(m_localInfo));
	m_clientInfo.client_id = 0 ;
	test_tiger_cradtype = 0;
	m_last_transfer_end_time = 0;
	m_last_login_time = 0;
}

FrontClientHandler::~FrontClientHandler()
{

}

//用户游戏断开
void FrontClientHandler::handle_close( TEventHandler * object )
{
	if ( m_player )
	{
		BYTE card_type = 0;
		if ( m_player->isNormalPlayer() )
		{
			if ( m_player->getTable()  ) //在游戏中
			{
				if ( m_player->getTable()->isPlaying() )
				{
					//printf("player = %u close in table = %d chair = %d and playing to closelist\n",m_player->get_user_id() , m_player->getTable()->getTableId(),m_player->get_chair_id() );
					WL(LL_INFO,"player = %u close int table = %d chair = %d and playing to closelist\n",
						m_player->get_user_id() , m_player->getTable()->getTableId(),m_player->get_chair_id() );
					//m_player->getTable()->leaveTable( m_player );
					CloseConnsList::instance()->add( this );
					if(m_player == NULL)
						return;
					ActiveConnsList::instance()->remove( m_player->get_user_id() );
					return ;
				}
				else
				{
					//printf("player = %u close in table = %d not playing  table_status:%d \n", m_player->get_user_id() , m_player->getTable()->getTableId()  ,m_player->getTable()->getTableStatus());
					WL(LL_INFO,"player = %u close int table = %d not playing \n", m_player->get_user_id() , m_player->getTable()->getTableId() );
					//g_pFlowLog->logMsg("player = %u close int table = %d not playing \n", m_player->get_user_id() , m_player->getTable()->getTableId() );
					//m_player->getTable()->leaveTable( m_player );
					CloseConnsList::instance()->add( this );
					if(m_player == NULL)
						return;
					ActiveConnsList::instance()->remove( m_player->get_user_id() );
					
					if(m_player->GetCurRoomID() == ROOM_CONFI_ID_BRC)/*???ڰ?˳?*/
					{
						WL(LL_INFO,"player = %u close int table  in brc svr \n", m_player->get_user_id());
						CBrcMsgHandle::instance()->NotifyClientCloseToBrcSvr(m_player->get_user_id());
					}
					return ;
				}
			}
		}
		else
		{
			if ( m_player->getTable()  ) //在游戏中
			{
				WL(LL_INFO,"player = %u close in table = %d not playing \n", m_player->get_user_id() , m_player->getTable()->getTableId() );
				m_player->getTable()->leaveTable( m_player );
			}
		}
		
	}
	
	if(m_player)
	{
		m_player->NotifyStatusToFriend(0);
		WL(LL_INFO, "zq  player = %u, socket = %d close addr:0x%x\n", m_player->get_user_id(), get_handle() ,m_player);
	}
	ActiveConnsList::instance()->release( this );
	
}

void FrontClientHandler::handlePacket( Packet* packet )
{
	struct timeval t_start, t_end;
    long cost_time = 0;
	gettimeofday(&t_start, NULL);
	if ( packet->getCmd() != 0x1025 && packet->getCmd() != 0x71  )
	{
		//printf( "zq 1 handlePacket cmd = 0x%02X, time = %llu \n",packet->cmd, time(NULL) );
	}
	if ( !decodePacket( packet) ) return ;
	//printf( "zq 2 handlePacket cmd = 0x%02X, time = %llu \n",packet->cmd, time(NULL) );

// 	if (m_player && m_player->isNormalPlayer() && packet->cmd != MSG_REQ_HEARTBEAT)
// 	{
// 		printf("%s: cmd %u\n", __FUNCTION__, packet->cmd);
// 	}
	
	if ( (packet->cmd  & 0xff00) == MSG_BRC_SERVER_FLAG )
	{
		//百人场消息
		if ( (packet->cmd & 0x00ff) == MSG_SERVER_BRC_REGISTER )
		{
			CBrcMsgHandle::instance()->SetServerHandle( this );
		}
		else
		{
			CBrcMsgHandle::instance()->OnServerMsg( packet );
		}
		return;
	}
	else if( (packet->cmd  & 0xff00) == MSG_BRC_CLIENT_FLAG )
	{
		CBrcMsgHandle::instance()->OnPlayerMsg( packet, this );
		return;
	}
	switch ( packet->cmd )
	{
		case MSG_REQ_HEARTBEAT:
			{
				//packet->setCmd( MSG_RESP_HEARTBEAT );
				
				this->safeSend( packet->getPacketData() , packet->getPacketLen() );
				break;
			}
		case MSG_HTTP_GET_ONLINE_PLAYERS:
			handleGetOnlinePayers( packet );
			break;
		case MSG_REQ_Sign_Data://用户主动请求签到数据
			{
				SendSignInData( m_player );
				break;
			}
		case MSG_HTTP_RUNNING_INFO:
			handleGetRunningInfo( packet );
			break;
		case MSG_REQ_RECHARGE:
			handleFillGold( packet );
			break;
		case MSG_REQ_LUCKY:
			handleProcLucky( packet );
			break;
		//登录处理
		case MSG_REQ_LOGIN:
			handleLogin( packet );
			break;
		case MSG_REQ_USER_DETAIL:
			handleUserDetail( packet );
			break;
		case MSG_REQ_EMAIL_LIST:
			handleEmailList( packet );
			break;
		case MSG_REQ_TASK_LIST:
			handleTaskList( packet );
			break;
		case MSG_REQ_HONGBAO_TASK_LIST:
			handleHongbaoTaskList( packet );
			break;

		case MSG_REQ_HONGBAO_NUM:
			handleHongbaoNum( packet );
			break;
		case MSG_REQ_FREE_HONGBAO:
			handleFreeHongbao( packet );
			break;
		case MSG_REQ_OPEN_HONGBAO:
			handleOpenHongbao( packet );
			break;
		case MSG_REQ_HONGBAO_HISTORY:
			handleHongbaoHistory( packet );
			break;
			
		case MSG_REQ_EXCH_RECORD:
			handleExchangeRecord( packet );
			break;
		case MSG_HTTP_NOTIFY_RELOAD:
			break;
		//注册处理
		case MSG_REQ_REGISTER:
			handleRegister( packet );
			break;
		case MSG_REQ_FAST_REGISTER:
			handleRegister( packet , true );
			break;
		case MSG_REQ_UPDATE_USER:
			handleUpdateUserInfo( packet );
			break;
		case MSG_REQ_BIND_ACCOUNT:
			handleBindAccount( packet );
			break;
		case MSG_REQ_BIND_PHONE:
			handleBindPhone( packet );
			break;
		case MSG_REQ_RECV_TASK_BONUS:
			handleReceiveTaskBonus( packet );
			break;
		case MSG_REQ_RECV_HONGBAO_TASK_BONUS:
			handleReceiveHongbaoTaskBonus( packet );
			break;
		case MSG_REQ_EXCH_COMMODITY:
			handleExchangeProduct( packet );
			break;
		case MSG_REQ_RECOMMEND_AWARD:
			handleRecommendAward( packet );
			break;
		case MSG_REQ_QUERY_ONLINE://获取在线人数
			handleGetOnline( packet );
			break;
		case MSG_REQ_ENTER_ROOM://进入桌子
			{
				printf("MSG_REQ_ENTER_ROOM  \n");
				checkUserMoneyLegal();
				handleEnterRoom( packet );
			}
			break;
		case MSG_REQ_CHANGE_TABLE://换桌
			{
				handleEnterRoom(packet);
			}
			break;
		case MSG_REQ_ROOM_LIST:
			handlePrivateRoomList( packet );
			break;
		case MSG_REQ_APPLY_PWD_TABLE:
			handleCreatePrivateRoom( packet );
			break;
		case MSG_REQ_NOTIFY_CHARGE_RESULT:
			handleHttpNotifyChargeStatus( packet );
			break;
		case MSG_REQ_CHARGE_INFO:
			handleChargeInfo( packet );
			break;
		case MSG_REQ_NOTIFY_TRADE_STATUS:
			handleHttpNotifyChargeStatus( packet );
			break;
		case MSG_REQ_CREATE_CHARGE_ORDER:
			handleCreateOrder( packet );
			break;
		case MSG_HTTP_DISABLE_CONN:
			FrontLisentor::instance()->disable_connect();
			break;
		case MSG_REQ_BROADCAST:
			handleBroadcast( packet );
			break;
		case MSG_SYSTEM_BROADCAST:
			handleSystemBroadcast( packet );
			break;
		
		case MSG_REQ_INIT_ROULETTE:
			handleInitRoulette( packet );
			break;
		case MSG_REQ_INIT_SLOT:
			handleInitSlot( packet );
			break;
		case MSG_REQ_BET_ROULETTE:
			handleBetRoulette( packet );
			break;
		case MSG_REQ_BET_SLOT:
			handleBetSlot( packet );
			break;
		case MSG_REQ_COMMODITY_LIST:
			handleGetCommodityList( packet );
			break;
		case MSG_REQ_EXCH_LIST:
			handleGetExchCommodityList( packet );
			break;
		case MSG_REQ_SORT: //获取排行榜数据，流程1
			handleGetRankingList( packet );
			break;
		case MSG_REQ_DEPOSIT:
			handleDeposit( packet );
			break;
		case MSG_REQ_WITHDRAW:
			handleWithdraw( packet );
			break;
		case MSG_REQ_LEAVE_ROOM:
		case MSG_REQ_LEAVE_CHAIR:
			{
				if ( m_player && m_player->getTable() )
				{
					m_player->getTable()->handlePacket( packet , m_player );
				}
			}
			break;
		case MSG_REQ_RESTORE_SCENE:
			handleRestoreScene( packet );
			break;
		case MSG_REQ_GET_HELP_GOLD:
			handleGetHelpGold( packet );
			break;
		case MSG_REQ_GET_SIGN_IN_REWARD:
			handleGetSignInReward( packet );
			break;
		case MSG_REQ_LOGIN_REWARD_BOX:
			handleGetLoginRewardBox( packet );
			break;
		case MSG_REQ_RECONNECT_SERVER:
			handleReConnectServer( packet );
			break;
		case MSG_REQ_GEM_SWAP_GOLDS:
			handleGemSwapGolds( packet );
			break;
		case MSG_REQ_CHANGE_HEAD_PICTURE:
			handleUpdateHeadPicture( packet );
			break;
		case MSG_REQ_ADD_FRIEND:
			handleReqAddFriend( packet );
			break;
		case MSG_REQ_DELETE_FRIEND:
			handleReqDeleteFriend( packet );
			break;
		case MSG_REQ_SEND_MSG_TO_FRIEND:
			handleReqSendMsgToFriend( packet );
			break;
		case MSG_REQ_ANSWER_ADD_FRIEND:
			handleReqAnswerAddFriend( packet );
			break;
		case MSG_REQ_GET_FRIEND_LIST:
			handleReqGetFriendList( packet );
			break;
		case MSG_REQ_GET_FRIEND_LIST_EX:
			handleReqGetFriendListEx( packet );
			break;
		case MSG_REQ_GIVE_PLAYER_GIFT:
			handleReqGivePlayerGift( packet );
			break;
		case MSG_REQ_CLEAR_EGGS:
			handleReqClearEggs( packet );
			break;
		case MSG_REQ_SELL_GIFT:
			handleReqSellGift( packet );
			break;
		case MSG_REQ_LOTTERY_BEGIN:
			handleReqLotteryBegin( packet );
			break;
		case MSG_REQ_LOTTERY_SWAP:
			handleReqLotterySwap( packet );
			break;
		case MSG_REQ_LOTTERY_END:
			handleReqLotteryEnd( packet );
			break;
		case MSG_REQ_EMAIL_DELETE:
			handleReqEmailDelete( packet );
			break;
		case MSG_REQ_ENEMY_LIST:
			handleReqEnemyList( packet );
			break;
		case MSG_REQ_INVITE_FRIEND_GAME:
			handleReqInviteFriendGame( packet );
			break;
		case MSG_REQ_SIGN_IN:
			{
				ReqSignIn( packet );
				break;
			}
		case MSG_REQ_WITHDRAW_PASSWD:
			{
				handleUpdateDepositPwd( packet );
				break;
			}
		case MSG_REQ_UPDATE_NICKNAME:
			{
				handleUpdateNickName( packet );
				break;
			}
			//时时彩
		case MSG_REQ_LOTTERY_BET:
			{
				StreamReader reader( packet->getData() );
				BYTE bettype = reader.get_byte();
				//GameLotteryMgr::instance()->OnPlayerBet( m_player->get_user_id(), bettype, this );
				break;
			}
		case MSG_REQ_TRANSFER_GOLD:
			handleTransferGold( packet );
			break;
		case MSG_REQ_TRANSFER_GOLD_RECORD:
			handleTransferGoldRecord( packet );
			break;
		case MSG_REQ_FRIEND_SEND_MESSAGE:
			handleFriendChat( packet );
			break;
		case MSG_REQ_LOTTERY_DRAW:
			handleLotteryDraw( packet );
			break;
		case MSG_REQ_UPDATE_WEALTH:
			handleGetWealthFromDB( packet );
			break;
		case MSG_REQ_HISTORY_MESSAGE:
			ReadFriendChatRecord( packet );
			break;
		case MSG_REQ_DELETE_PRI_TABLE:
			handleDeleteTable( packet );
			break;
		case MSG_STATUS_INFO_REQ:
			{
				GameLotteryNew::instance()->onLotteryInfoReq(this);
			}
			break;
		case MSG_CAIPIAO_BET_REQ:
			{
				StreamReader reader(packet->getData());
				int betGold = reader.get_int();
				BYTE  dir = reader.get_byte();
				GameLotteryNew::instance()->onPlayerBuyLottery(dir, betGold, this);
			}
			break;
		case MSG_CAIPIAO_ZOUSHI_REQ:
			GameLotteryNew::instance()->handleZouShiPush(this);
			break;
		case MSG_IP_REPORT_REQ:
			handleClientReportIP(packet);
			break;
		case MSG_REQ_COMMAND_HONGBAO_SHANGJIA:
			{
				StreamReader reader(packet->getData());
				int money = reader.get_int();
				HongbaoLogic::instance()->command_hongbao_shangjia(this, money);
			}
			break;
		case MSG_REQ_COMMAND_HONGBAO_GET:
			{
				StreamReader reader(packet->getData());
				int command_code = reader.get_int();
				HongbaoLogic::instance()->get_command_hongbao(this, command_code);
			}
			break;
		case MSG_REQ_COMMAND_HONGBAO_CONFIRM:
			{
				StreamReader reader(packet->getData());
				int command_code = reader.get_int();
				BYTE type = reader.get_byte();
				HongbaoLogic::instance()->command_hongbao_confirm(this, command_code, type);
			}
			break;
		case MSG_REQ_GET_COMMAND_HONGBAO_RECORD:
			{
				HongbaoLogic::instance()->get_command_hongbao_record(this);
			}
			break;
		case MSG_SHARE_REWARD_REQ:
			{
				StreamReader reader(packet->getData());
				int secne_id = reader.get_int();
				BYTE type = reader.get_byte();
				handleShareReward(secne_id, type);
				
			}
			break;
		default:
			if ( m_player && m_player->getTable() ){
				m_player->getTable()->handlePacket( packet , m_player );
			}
			else{
				WL(LL_WARNING,"player = %u cmd = 0x%02X unkow handle\n", m_player ? m_player->get_user_id() : 0 ,packet->cmd );
			}
			break;
	}


	//get end time
	gettimeofday(&t_end, NULL);
	//printf("End time: %ld us", t_end.tv_usec);

	//calculate time slot
	cost_time = t_end.tv_usec - t_start.tv_usec;

	//WL(LL_DEV, "End time: %ld us, Cost time: %ld us \n", t_end.tv_usec, cost_time);
}

bool FrontClientHandler::decodePacket( Packet* packet )
{
//	if ( !(	   packet->cmd >= MSG_HTTP_NOTIFY_RELOAD 
//		|| packet->cmd == MSG_REQ_NOTIFY_TRADE_STATUS ) )
	if ( (packet->cmd < 0x8000) || (packet->cmd >= 0x9000) )
	{
			decrypt( packet->getData() , packet->getDataLen() , packet->get_enc_key()  );
	}
	return true ;
}

void FrontClientHandler::sendSvrPacket( BYTE cmd ,u8_t * data , int len )
{
	if ( len > 0 && !isClosed() )
	{
// 		this->sockRC4( data , len );
// 		u32_t crc = this->calcCRC( data , len);
// 		this->sendPacket( cmd , data , len ,0 , crc );
	}
}

void FrontClientHandler::procDataBaseReturn( SQLResp * resp  )
{
	if ( (resp->req_type >= REQ_TYPE_BRC_XZ) && (resp->req_type <= 0x10ff) )
	{
		CBrcMsgHandle::instance()->OnDBMsg( resp->req_type, resp, this );
		return;
	}
	switch ( resp->req_type )
	{
	case REQ_TYPE_LOGIN:
		handleLoginResult( resp );
		break;
	case REQ_TYPE_REGISTER:
		handleRegisterResult( resp );
		break;
	case REQ_TYPE_EMAIL_LIST:
		handleEmailListResult( resp );
		break;
	case REQ_TYPE_TASK_LIST:
		handleTaskListResult( resp );
		break;
	case REQ_TYPE_HONGBAO_TASK_LIST:
		handleHongbaoTaskListResult( resp );
		break;

	case REQ_TYPE_HONGBAO_NUM:
		handleHongbaoNumResult( resp );
		break;
	case REQ_TYPE_FREE_HONGBAO:
		handleFreeHongbaoResult( resp );
		break;
	case REQ_TYPE_OPEN_HONGBAO:
		handleOpenHongbaoResult( resp );
		break;
	case REQ_TYPE_HONGBAO_HISTORY:
		handleHongbaoHistoryResult( resp );
		break;
		
	case REQ_TYPE_EXCHAGE_PRODUCT:
		handleExchangeProductResult( resp );
		break;
	case REQ_TYPE_TASK_REWARD:
		handleReceiveTaskBonusResult( resp );
		break;
	case REQ_TYPE_HONGBAO_TASK_REWARD:
		handleReceiveHongbaoTaskBonusResult( resp );
		break;
	case REQ_TYPE_RECOMMEND_AWARD:
		handleRecommendAwardResult( resp );
		break;
	case REQ_TYPE_ONLINE_REWARD:
		handleOnlineRewardResult( resp );
		break;
	case REQ_TYPE_CHARGE_INFO:
		handleChargeInfoResult( resp );
		break;
	case REQ_TYPE_CREATE_ORDER:
		handleCreateOrderResult( resp );
		break;
	case REQ_TYPE_HTTP_COMMIT_CHARGE_RESULT:
		handleHttpNotifyChargeStatusResult( resp );
		break;
	case REQ_TYPE_EXCHAGE_RECORD:
		handleExchangeRecordResult( resp );
		break;
	case REQ_TYPE_UPDATE_USER_INFO:
		handleUpdateUserInfoResult( resp );
		break;
	case REQ_TYPE_FRIEND_GET_LIST:
		handleGetFriendListResult( resp );
		break;
	case REQ_TYPE_GET_USER_DETAIL:
		handleGetUserDetailResult( resp );
		break;
	case REQ_TYPE_FRIEND_ADD_BY_GFIT:
		handleFriendAddByGiftResult( resp );
		break;
	case REQ_TYPE_ENEMY_GET_LIST:
		handleGetEnemyListResult( resp );
		break;
	case REQ_TYPE_SIGNIN:
		RespSignInResult(resp);
		break;
	case REQ_TYPE_BIND_ACCOUNT:
		handleBindAccountResult( resp );
		break;
	case REQ_TYPE_BIND_PHONE:
		handleBindPhoneResult( resp );
		break;
	case REQ_TYPE_TIGER:
		handleBuyTigerResult(resp);
		break;
	case REQ_TYPE_DEPOSIT_BOX:
		handleDepositResult( resp );
		break;
	case REQ_TYPE_DEPOSIT_BOX_PWD:
		handleUpdateDepositPwdResult( resp );
		break;
	case REQ_TYPE_UPDATE_NICKNAME:
		handleUpdateNickNameResult( resp );
		break;
	case REQ_TYPE_LOTTERY_HANDLE:
		//GameLotteryMgr::instance()->OnDBMsg( resp, this );
		break;
	case REQ_TYPE_UPDATE_TASK:
		break;
	case REQ_TYPE_SEND_HORN:
		handleSendHornResult( resp );
		break;
	case REQ_TYPE_STRANSFER_GOLD:
		handleTransferGoldResult( resp );
		break;
	case REQ_TYPE_STRANSFER_GOLD_RECORD:
		OnDBTransferGoldRecord( resp );
		break;
	case REQ_TYPE_LOTTERYDRAW:
		OnDBLotteryDraw( resp );
		break;
	case REQ_TYPE_GET_CHAT_MESSAGE:
		OnDBReadFriendChatRecord( resp );
		break;
	case REQ_TYPE_GET_USER_WEALTH:
	case REQ_TYPE_GET_USER_WEALTH_EX:
		OnDBUpdateWealth( resp );
		break;
	case REQ_TYPE_USER_SELL_BUY_GOODS:
		OnDBBuyOrSellGoods( resp  );
		break;
	case REQ_TYPE_SELL_GIFT:
		OnDBSellGift( resp );
		break;
	case REQ_TYPE_FRIEND_GIVE_GFIT:
		OnDBGiveGift( resp );
		break;
	case REQ_TYPE_DELETE_TABLE:
		OnDBDeleteTable( resp );
		break;
	case REQ_TYPE_CLEAR_LASTDAY_VAR:
		OnDBClearLastDayVar( resp );
		break;
	case REQ_TYPE_ENTER_ROOM:
		onDBGetGold(resp);
		break;
	case REQ_TYPE_SHISHI_CAI:
		GameLotteryNew::instance()->OnDBMsg(resp, this);
		break;
	case REQ_TYPE_LIANG_HAO:
		LiangHao::instance()->OnDBMsg(resp, this);
		break;
	case REQ_TYPE_DUOBAO:
		onDbGetDuobaoNotify(resp);
		break;
	case REQ_TYPE_COMMAND_HONGBAO:
	case REQ_TYPE_GET_HONGBAO:
	case REQ_TYPE_HONGBAO_CONFIRUM:
	case REQ_TYPE_HONGBAO_RECORD:
		HongbaoLogic::instance()->OnDBMsg(resp, this);
		break;
	case REQ_TYPE_SHARE_REWARD:
		onDbGetShareReward(resp);
		break;
	default:
		WL(LL_WARNING,"handle result cmd = %d not found\n",resp->req_type);
		break;
	}
}

void FrontClientHandler::handleGetOnline( Packet* packet )
{
	StreamPacketBuilder::instance()->handleGetOnline( this );
}

void FrontClientHandler::handleBroadcast( Packet* packet )
{
	if ( m_player )
	{
		int usegold = 3000;
		map< int , GameDataConfig >::iterator iter = Config::instance()->m_gamedataconfig.find( DATA_CONFIG_HORN_GOLD );
		if ( iter != Config::instance()->m_gamedataconfig.end() )
		{
			usegold = iter->second.valuelist[0];
		}
		
		INT64 golds = m_player->get_user_enable_gold();//用户可能金币数
		TableBase* pTable = m_player->getTable();
		RoomDirector * roomDirector = RoomManager::instance()->findRoom( m_player->GetCurRoomID() ) ;
		int mingold = 0;
		if ( roomDirector )
		{
			mingold = roomDirector->getRoom()->lower_limit_gold;
		}
		//printf( "zq  mingold = %d\r\n", mingold );
		//如果在房间则要判断房间的最小金币数
		if (  golds < (usegold + mingold) )
		{
			StreamPacketBuilder::instance()->respBroadcast( this , ERR_NOT_ENOUGH_GOLDS, m_player->get_user_enable_gold()  );  //回复
			return ;
		}
		
		//m_player->set_user_gold(golds - usegold);
		//m_player->OnUseLaba();
		//StreamPacketBuilder::instance()->respBroadcast( this , RESULT_OK, m_player->get_user_gold() ) ; //回复
		//StreamPacketBuilder::instance()->notifyBroadcast( m_player , packet->getData() , packet->getDataLen() ) ; //回复
		//StreamPacketBuilder::instance()->notifyUpdatePlayerGold(  m_player->getTable(), m_player );					//通知金币更新
		//printf( "zq ==== sned horn!!!!!!!!!!! packet->getDataLen() = %d\r\n", packet->getDataLen() );
		//更新数据库数据

		int nLabaCountLimit = Config::instance()->m_send_laba_limit;
		if(nLabaCountLimit != 0 && (m_player->get_user_win_count() + m_player->get_user_lost_count()) < nLabaCountLimit)
		{
			StreamPacketBuilder::instance()->respBroadcast( this , ERR_LABA_NEWER_LIMIT, m_player->get_user_enable_gold()  );
			return;
		}
		SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_SEND_HORN , this );
		req->id = m_player->get_user_id();
		SEND_HORN* hornmsg = (SEND_HORN*)req->sql;
		hornmsg->gold = usegold;
		hornmsg->type = 1;
		hornmsg->userid = m_player->get_user_id();
		int len = (packet->getDataLen() >= sizeof(hornmsg->content)) ? sizeof(hornmsg->content) - 1 : packet->getDataLen();
		memcpy( hornmsg->content, packet->getData(), len );
		hornmsg->len = len;
		DataBaseReadThreadPool::instance()->pushQueue( req );
	}
}

void FrontClientHandler::handleSendHornResult( SQLResp * resp )
{
	if (!m_player)
	{
		return;
	}
	DB_SEND_HORN_RESULT* pRetMsg = (DB_SEND_HORN_RESULT*)resp->data;
	//printf( "zq ==== handleSendHornResult \r\n" );
	if ( !resp->result || (pRetMsg->result != 0)  ) 
	{
		//数据库执行错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_BROADCAST , ERR_SYSTEM  );
		return ;
	}
	//大厅以数据库金币为准
	//INT64 curgold = pRetMsg->gold - m_player->getTableCoin();
	INT64 curgold = pRetMsg->gold;
	curgold = curgold < 0 ? 0 : curgold;
	if ( curgold != (m_player->get_user_gold() - m_player->getTableCoin() - pRetMsg->usegold)  )
	{
		printf( "zq error handleSendHornResult  gold is error  curgold = %lld %lld %d %d \r\n", curgold, m_player->get_user_gold(), m_player->getTableCoin(), pRetMsg->usegold );
	}
	m_player->set_user_gold( curgold);
	m_player->OnUseLaba();
	//printf( "zq ret pRetMsg->len = %d \r\n", pRetMsg->len );
	StreamPacketBuilder::instance()->notifyBroadcast( m_player , (u8_t*)pRetMsg->content , pRetMsg->len ) ; //发送喇叭
	StreamPacketBuilder::instance()->notifyUpdatePlayerGold(  m_player->getTable(), m_player );					//通知金币更新
#if 0
	//发给游戏服务器
	SEND_HORN hornmsg = {0};
	hornmsg.gold = pRetMsg->usegold;
	hornmsg.userid = m_player->get_user_id();
	CServerManager::instance()->LobbyServerSendToGS( MSG_GL_SEND_HORN, (char*)&hornmsg, sizeof(SEND_HORN) );
#endif
}


void FrontClientHandler::handleSystemBroadcast( Packet* packet )
{
	if(m_player == NULL)
		return;
	StreamPacketBuilder::instance()->notifySystemBroadcast( packet->getData() , packet->getDataLen() ,m_player->get_user_id()) ;; //回复
}
//机器人加金币
void FrontClientHandler::handleFillGold(Packet* packet)
{
	if ( m_player == NULL ) return ;

	StreamReader reader( packet->getData() );
	int		room_id	= reader.get_int();		//房间ID
	RoomItem * item = Config::instance()->get_room( room_id );
	if ( item && !m_player->isNormalPlayer() )
	{
		DWORD gold = item->room.lower_limit_gold  ;
		WL(LL_DEBUG ,"user_id = %u balance = %lld \n",m_player->get_user_id(),m_player->get_user_gold() );
		SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		snprintf( req->sql , sizeof(req->sql),"call p_rechange_gold(%u,%lld,%u)",
			m_player->get_user_id(),m_player->get_user_gold(),gold);
		m_player->add_user_gold( gold );
		DataBaseCommitThread::instance()->push( req )  ;
		StreamPacketBuilder::instance()->handleFillGold( m_player , room_id , gold );
	}
// 	else
// 	{
// 		StreamPacketBuilder::instance()->respError( m_player ,MSG_RESP_RECHARGE , ERR_NOT_ENOUGH_PROP ) ;
// 	}
}

void FrontClientHandler::handleInitRoulette( Packet* packet )
{
	StreamPacketBuilder::instance()->handleInitRoulette( m_player );
}

void FrontClientHandler::handleBetRoulette( Packet* packet )
{
}

void FrontClientHandler::handleInitSlot( Packet* packet )
{
	StreamPacketBuilder::instance()->handleInitSlot( m_player );
}

void FrontClientHandler::handleBetSlot( Packet* packet )
{
}

void FrontClientHandler::handleGetCommodityList( Packet* packet )
{
	if ( m_player == NULL ) return ;
	LocalInfo  * local_info = m_player->get_local_info();
	StreamPacketBuilder::instance()->handleGetCommodityList( this , local_info->channel );
}

void FrontClientHandler::handleGetExchCommodityList( Packet* packet )
{
	if ( m_player == NULL ) return ;
	LocalInfo  * local_info = m_player->get_local_info();
	StreamPacketBuilder::instance()->handleGetExchCommodityList( this , local_info->channel );
}

//获取排行榜数据，流程3
void FrontClientHandler::handleGetRankingList( Packet* packet )
{
	if ( m_player == NULL )
	{
		return ;
	}

	//printf("handleGetRankingList...\n");

	//发送
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(MSG_REQ_SORT , this );
	req->id = m_player->get_user_id();
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

//数据库返回排行榜，流程4
void FrontClientHandler::handleGetRankingListResult(SQLResp * resp)
{
	//printf("handleGetRankingListResult...\n");
	if (!m_player)
	{
		return;
	}

	if ( !resp->result  ) 
	{
		//数据库执行错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_SORT , ERR_SYSTEM_REPAIR  );
		return;
	}
	else
	{
		FrontClientHandler * handler = m_player->get_handler();
		StreamPacketBuilder::instance()->respOk( this ,MSG_RESP_SORT , resp->data, resp->len  );
		return;
	}
}

//存款
void FrontClientHandler::handleDeposit( Packet* packet )
{
	if ( m_player == NULL )
	{
		return ;
	}

	if(m_player->getTable() != NULL)
	{
		WL(LL_INFO, "nUserID:%d operate bank in room \n", m_player->get_user_id());
		return;
	}
	
	StreamReader reader ( packet->getData() );
	DWORD deposit = reader.get_uint(); 
	//printf( "zq handleDeposit %lld \r\n", deposit );
	//用户在游戏中不能使用
	if ( m_player->isPlaying() )
	{
		//printf( "zq handleDeposit m_player->isPlaying() \r\n" );
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_DEPOSIT , ERR_DEPOSIT_PLAYING );
		return;
	}
	UserInfo userinfo = m_player->getUserInfo();
	
	INT64  maxdepositgold = Config::instance()->m_vipconfigmap[userinfo.viplevel].maxgoldnum;

	if ( (maxdepositgold != -1) && (deposit > maxdepositgold) )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_DEPOSIT , ERR_DEPOSIT_EXCEED_LIMIT );
		return;
	}

	if(deposit > m_player->get_user_gold())
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_DEPOSIT ,  ERR_DEPOSIT_NOTENOUGH);
		return;
	}

	m_player->add_user_gold(-deposit);
	
	//IN `in_user_id` int, IN `in_type` int, IN `in_gold` bigint,IN `in_deposit_limit` bigint
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_DEPOSIT_BOX , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_deposit(%u, %d, %lld, %lld)",  userinfo.user_id,1, deposit,maxdepositgold);
	//printf( "zq handleDeposit eq->sql = %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

//存/取款返回
void FrontClientHandler::handleDepositResult(SQLResp * resp)
{

	if (!m_player)
	{
		return;
	}
	DBDepositRetMsg *pRetMsg = (DBDepositRetMsg *)resp->data;
	DWORD msgid = (pRetMsg->type == 1) ? MSG_RESP_DEPOSIT : MSG_RESP_WITHDRAW;
	if ( !resp->result )
	{
		StreamPacketBuilder::instance()->respError( this ,msgid , ERR_DEPOSIT_UNKNOW );
		return;
	}

	
	if ( pRetMsg->result != 0)
	{
		m_player->set_user_gold(pRetMsg->usergold);
		StreamPacketBuilder::instance()->respError( this ,msgid , pRetMsg->result );
		return;
	}

	
	m_player->set_user_gold( pRetMsg->usergold);
	m_player->setdepositgold( pRetMsg->depositgold );

	//通知用户
	char senddata[1024];
	StreamWriter stream_out(senddata, sizeof(senddata));
	stream_out.add_byte( RESULT_OK );	//结果
	stream_out.add_byte( pRetMsg->type );	//1:存 2:取
	stream_out.add_int64( pRetMsg->usergold );//用户当前金币数
	stream_out.add_int64( pRetMsg->depositgold );//用户存款数
	sendPacket( msgid, senddata, stream_out.get_buffer_len());
	//printf( "zq handleDepositResult  MSG_RESP_DEPOSIT  gold:%lld, despoit:%lld\r\n", pRetMsg->usergold, pRetMsg->depositgold );
	StreamPacketBuilder::instance()->notifyUpdatePlayerGold( m_player->getTable(), m_player );
}

//取款
void FrontClientHandler::handleWithdraw( Packet* packet )
{
	if ( m_player == NULL )
	{
		return ;
	}

	
	if(m_player->getTable() != NULL)
	{
		WL(LL_INFO, "nUserID:%d operate bank in room  table_id\n", m_player->get_user_id(), m_player->get_table_id());

	}

	StreamReader reader( packet->getData() );
	DWORD depositgold = reader.get_uint();
	BYTE pwdlen = reader.get_short();
	char  depositpwd[8] = {0};
	pwdlen = (pwdlen > 8) ? 8 : pwdlen;
	memcpy( depositpwd, reader.get_current_ptr(), pwdlen );

	if( (m_player->getTable() != NULL) && m_player->getTable()->getRoomConf() != NULL && m_player->getTable()->getRoomConf() ->room_type == ROOM_TYPE_NIUNIU )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_WITHDRAW , ERR_DEPOSIT_PLAYING );
		return ;
	}

	//printf( "depositpwd:%s m_player->getUserInfo().get_deposit_pwd() = %s\r\n", depositpwd, m_player->getUserInfo().get_deposit_pwd() );
	//要取的金币数大于存款数
	if ( depositgold > m_player->getUserInfo().get_deposit_gold() )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_WITHDRAW , ERR_DEPOSIT_NOTENOUGH );
		return;
	}
	//对比密码
	if ( (strlen( m_player->getUserInfo().get_deposit_pwd() ) > 0) &&				//用户设置了密码
			( strcmp(depositpwd, m_player->getUserInfo().get_deposit_pwd()) )
		)		//比较密码
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_WITHDRAW , ERR_DEPOSIT_PWD_ERROR );
		return;
	}
	UserInfo userinfo = m_player->getUserInfo();
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_DEPOSIT_BOX , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_deposit(%u, %d, %lld, %lld)",  userinfo.user_id, 2, depositgold, 0);//最大限制取消
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

//设置或重置存钱箱的取款密码
void FrontClientHandler::handleUpdateDepositPwd( Packet* packet )
{
	if ( m_player == NULL )
	{
		return ;
	}
	char newpwd[8] = {0};
	char oldpwd[8] = {0};

	StreamReader reader( packet->getData() );
	BYTE pwdlen = reader.get_short();
	//printf( "pwdlen = %d\r\n", pwdlen );
	pwdlen = (pwdlen > 8) ? 8 - 1 : pwdlen;
	if ( pwdlen > 0 )
	{
		memcpy( oldpwd, reader.get_current_ptr(), pwdlen );
	}
	reader.skip( pwdlen );
	pwdlen = reader.get_short();
	pwdlen = (pwdlen > 8) ? 8 - 1 : pwdlen;
	memcpy( newpwd, reader.get_current_ptr(), pwdlen );
	reader.skip( pwdlen );
	memcpy( m_player->m_updatepwd, newpwd, pwdlen  );
	BYTE bresetpwd = reader.get_byte();


	//printf( "newpwd = %s  oldpwd = %s   userpwd: %s  bresetpwd:%d\r\n", newpwd, oldpwd, m_player->getUserInfo().get_deposit_pwd(), bresetpwd );
	if ( (!bresetpwd) && (strcmp(m_player->getUserInfo().get_deposit_pwd(), oldpwd)) )
	{
		StreamPacketBuilder::instance()->respError( this, MSG_RESP_WITHDRAW_PASSWD , ERR_DEPOSIT_PWD_ERROR );
		return;
	}
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_DEPOSIT_BOX_PWD , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"UPDATE user_info SET deposit_pwd = '%s' WHERE user_id = %u; ",  newpwd, m_player->get_user_id() );
	//printf( "zq  deposit pwd  req->sql = %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

//取款密码返回
void FrontClientHandler::handleUpdateDepositPwdResult(SQLResp * resp)
{
	if (!m_player)
	{
		return;
	}

	//StreamPacketBuilder::instance()->handleGetRankingList( this  );
	//return;

	if ( !resp->result  ) 
	{
		//数据库执行错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_WITHDRAW_PASSWD , 1  );
		return;
	}
	else
	{
		StreamPacketBuilder::instance()->respOk( this ,MSG_RESP_WITHDRAW_PASSWD , NULL, 0 );
		m_player->getUserInfo().set_deposit_pwd( m_player->m_updatepwd );
		return;
	}
}

void FrontClientHandler::handleGenaeralOrder( Packet* packet )
{

}

void FrontClientHandler::handleGetRunningInfo( Packet* packet )
{
	StreamPacketBuilder::instance()->handleGetRunningInfo( this  );
}

void FrontClientHandler::handleGetOnlinePayers( Packet* packet )
{
	StreamPacketBuilder::instance()->handleGetOnlinePayers( this  );
}

void FrontClientHandler::handleLogin( Packet* packet )
{
	unsigned long long now;
	struct  timeval    tv_start;
	gettimeofday(&tv_start,NULL);
	now = tv_start.tv_sec *1000000  + tv_start.tv_usec;
	if (now > m_last_login_time && now - m_last_login_time < 10 * 1000000)
	{
		if (m_login_count > 1)
		{
			WL(LL_ERROR ,"%s client %p[%d] m_login_count[%d] login too much\r\n", __FUNCTION__ , this, m_fd, m_login_count);
			return;
		}
	}
	else
	{
		m_login_count = 0;
	}
	++m_login_count;
	m_last_login_time = now;
	
	if ( m_player )
	{
		StreamPacketBuilder::instance()->respLogin( m_player );
		return ;
	}
	StreamReader reader( packet->getData() );
	const char * user_name	= reader.get_current_ptr();
	BYTE  length			= S_STRLEN( user_name ) ;
	reader.skip( length );
	const char * user_pwd	= reader.get_current_ptr();
	length					= S_STRLEN( user_pwd ) ;
	reader.skip( length );
	memset(&m_localInfo , 0 , sizeof(m_localInfo)) ;
	parse_local_info( reader ,m_localInfo );

	printf("login :%d \n", m_localInfo.channel);
	//读取三方id和用户昵称
	if ( reader.get_current_pos() < (packet->getDataLen() - 5) )
	{
		m_localInfo.externid = reader.get_uint();
		BYTE externnamelen = reader.get_byte();
		reader.skip( externnamelen );
		externnamelen = externnamelen > 31 ? 31 : externnamelen;
		memcpy( m_localInfo.extername, reader.get_current_ptr(), externnamelen );
		m_localInfo.extername[externnamelen] = '\0';
	}
#ifdef SHOW_DETIAL 	
	WL(LL_ERROR,"zq login name = -%s- user_pwd=-%s-  packet:len=%d gameversion = %s  externid = %d\r\n", user_name,user_pwd , packet->getDataLen(), m_localInfo.gameversion, m_localInfo.externid );
	printf("zq login name = -%s- user_pwd=-%s-  packet:len=%d gameversion = %s  externid = %d\r\n", user_name,user_pwd , packet->getDataLen(), m_localInfo.gameversion, m_localInfo.externid );
#endif

	//如果是第三方登入必须要有用户名
	if ( (m_localInfo.externid > 0) && (strlen(user_name) == 0) )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_LOGIN , ERR_USER_NOT_FOUND  );
		return ;
	}

	//用户名和密码都为空的时候是游客登入
	if ( (strlen(user_name) == 0) &&  (strlen(user_pwd) == 0) )
	{
		m_last_login_time = 0;		
		postRegisterQueue( m_localInfo , user_name , user_pwd , 1 );
	}
	else
	{
		string strGameV = m_localInfo.gameversion;
		string strImei = m_localInfo.imei;
		StreamPacketBuilder::instance()->filterSinglequotes(strGameV);
		StreamPacketBuilder::instance()->filterSinglequotes(strImei);
		/*SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		req->id = 0;
		snprintf( req->sql , sizeof(req->sql) ,"call p_check_login( %u, '%s','%s',%d, '%s', '%s', %u )",
			m_localInfo.externid, user_name ,user_pwd ,m_localInfo.channel, strGameV.c_str(), strImei.c_str(), htonl( get_address().get_long_addr() ) );
		req->client		= this ;
		req->req_type	= REQ_TYPE_LOGIN ;
		DataBaseReadThreadPool::instance()->pushQueue( req );*/




		SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		snprintf( req->sql , sizeof(req->sql) ,"call p_check_login( %u, '%s','%s',%d, '%s', '%s', %u )",
				m_localInfo.externid, user_name ,user_pwd ,m_localInfo.channel, strGameV.c_str(), strImei.c_str(), htonl( get_address().get_long_addr() ) );
		req->client		= this ;
		req->req_type	= REQ_TYPE_LOGIN ;

		struct  timeval    tv_start;
		gettimeofday(&tv_start,NULL);

		req->time_stamp = tv_start.tv_sec *1000000  + tv_start.tv_usec;
		DataBasePacketDataThread::instance()->push( req );

		
		
	}
}

void FrontClientHandler::handleLoginResult( SQLResp * resp )
{
	//printf( "zq handleLoginResult resp->result = %d \r\n", resp->result );

	//resp->result  = 1是用户账号正常
	if ( (resp->result == 0) || (resp->result == 2) )
	{
		//登录错误
		WL(LL_ERROR,"Login Rsp passwd err nUserID:%d [%p]\r\n", (( UserInfo *)resp->data)->user_id, this);
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_LOGIN , ERR_PASSWORD  );
		return ;
	}
	if ( resp->result == 3 )
	{
		//登录错误
		WL(LL_ERROR,"Login Rsp login_disable nUserID:%d [%p]\r\n", (( UserInfo *)resp->data)->user_id, this);
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_LOGIN , ERR_LOGIN_DISABLE  );
		return;
	}
	else if ( resp->result == 4 )
	{
		//登录错误
		WL(LL_ERROR,"Login Rsp resp->result == 4 [%p]  \r\n", this);
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_LOGIN , 100  );
		return;
	}

#ifdef SHOW_DETIAL 
	struct  timeval    tv_start;
	gettimeofday(&tv_start,NULL);
	WL(LL_DEV, " handleLoginResult  user time = %d  \n", tv_start.tv_sec *1000000  + tv_start.tv_usec - resp->time_stamp );
#endif

	
	m_player = GameMemoryPool::instance()->mallocPlayerClass();
	m_player->set_handler( this );
	UserInfo * userInfo = ( UserInfo *)resp->data ;
	memcpy( &m_player->getUserInfo() , userInfo , sizeof(UserInfo));
	if ( strlen( m_player->getUserInfo().version ) != 5 )
	{
		memcpy( m_player->getUserInfo().version, "1.0.0", 5 );
		m_player->getUserInfo().version[VERSION_LEN-1] = '\0';
	}
	m_clientInfo.client_id = userInfo->user_id ;

	//printf( "zq login success set data -> nickname:%s  total_win_counts = %d\r\n", m_player->getUserInfo().nick_name, m_player->getUserInfo().total_win_counts );
	if ( userInfo->broadcast_count > 0 )
	{
		PropItem * prop_item = m_player->getPropItems();
		m_player->set_props( 1 );
		prop_item [ 0 ].prop_id			= BROADCAST_PROD_ID ;
		prop_item [ 0 ].prop_count		= userInfo->broadcast_count;
		prop_item [ 0 ].prop_remain_day	= 1000;
	}

	FrontClientHandler * old_close_handler = CloseConnsList::instance()->find( userInfo->user_id );
	if ( old_close_handler ) 
	{	
		Player * old_close_player = old_close_handler->getPlayer();
		if (old_close_player) {
			m_player->set_table_id(old_close_player->get_table_id());

			TableBase * pOldTable = old_close_player->getTable();
			if (pOldTable) {
				RoomConfigItem * pOldConfig = pOldTable->getRoomConf();
				if (pOldConfig)
					m_player->set_room_id(pOldConfig->room_id);
			}
		}
	}
	
	FrontClientHandler * old_handler = ActiveConnsList::instance()->find( userInfo->user_id );

	if ( old_handler ) //存在
	{
		//一样的，没有
		if ( old_handler == this  ) return ; //不返回
		
		Player * old_player = old_handler->getPlayer();
		if (old_player) {
			UserInfo & old_user = old_player->getUserInfo();
			m_player->set_table_id(old_player->get_table_id());

			TableBase * pOldTable = old_player->getTable();
			if (pOldTable) {
				RoomConfigItem * pOldConfig = pOldTable->getRoomConf();
				if (pOldConfig)
					m_player->set_room_id(pOldConfig->room_id);
			} //!--?ʱ??ε? 20160805
			//memcpy( &m_player->getUserInfo() , &old_user , sizeof(UserInfo));
			
			if ( old_user.broadcast_count > 0 )
			{
				PropItem * prop_item = m_player->getPropItems();
				m_player->set_props( 1 );
				prop_item [ 0 ].prop_id			= BROADCAST_PROD_ID ;
				prop_item [ 0 ].prop_count		= old_user.broadcast_count;
				prop_item [ 0 ].prop_remain_day	= 1000;
			}
		}
		
		//不相等，两个socket
		if ( !old_handler->isClosed() ) //没有关闭
		{
			WL(LL_INFO, "old handle does not close add:0x%02x nUserID:%d \r\n", old_handler, old_handler->getClientId());
			StreamPacketBuilder::instance()->notifyOffLine( old_handler );
			old_handler->closeHandle() ; //在里面释放了active list
		}
		else
		{
			//已经关闭过了
			WL(LL_INFO, "login Rsp nUserID:%d had in ActiveConnsList \r\n", old_handler->getClientId());
			ActiveConnsList::instance()->release( old_handler );
		}
	}
	m_player->SetLoadTasks(false);
	m_player->OnEnterGame(true);
	if (m_player->IsNeedClearTask()) {
		RequestTaskListFromDB();
	}
	//根本取不到地址
	//getAddrName(); 
	if ( !ActiveConnsList::instance()->add( this ) ){
		closeHandle();
		return  ;
	}
	
	//游戏配置
	SendGameDataConfig( m_player );

	//用户临时数据
	//老虎机
	char cardsstr[6] = {0};
	memcpy( cardsstr, resp->data + sizeof(UserInfo), 6 );
	BYTE cards[3] = {0};
	int cardsint = strtol( cardsstr, NULL, 16 );
	cards[2] = cardsint & 0x00ff;
	cards[1] = (cardsint>>8) & 0x00ff;
	cards[0] = (cardsint>>16) & 0x00ff;
	//printf( "zq login cardsstr:%s tigercards: %x  %x %x \r\n",cardsstr, cards[0], cards[1], cards[2] );
	if ( cards[0] != 0 )
	{
		m_player->m_lottery_info.is_start = true;
		memcpy( m_player->m_lottery_info.lottery_card, cards, 3 );
		m_player->m_lottery_info.changenum = *(int*)((char*)resp->data + sizeof(UserInfo) + 6);
		m_player->m_lottery_info.buygold = *(int*)((char*)resp->data + sizeof(UserInfo) + 10);
		m_player->m_lottery_info.lucky_color = *(int*)((char*)resp->data + sizeof(UserInfo) + 14);
		//printf( "zq login changenum: %d  lucky_color: %d goldnum = %d \r\n", m_player->m_lottery_info.changenum, m_player->m_lottery_info.lucky_color, m_player->m_lottery_info.buygold );
	}
	
	StreamPacketBuilder::instance()->respLogin( m_player );
	int present = 0 ;
	writeLoginLog( htonl( get_address().get_long_addr()) , userInfo->user_id , m_localInfo ,present );
	// 获取仇人列表
	GetEnemyFromDB(m_player->get_user_id());
	LoadFriendData();
	//发送签到数据
	SendSignInData( m_player );

	changeUserOnlineStatus(0, m_player->get_user_id());

	handleGetUserDuoBaoNotfyContent(m_player->get_user_id());

	WL(LL_INFO, "nUserID:%d login sucess  addr:0x%02x handler[%p]!\r\n", m_player->get_user_id(), m_player, this);


}

void FrontClientHandler::getAddrName()
{
	m_clientInfo.ip			=  htonl( get_address().get_long_addr());
	m_clientInfo.area		= (char*)TIPDataBase::instance()->find_area_name( m_clientInfo.ip );
	//printf( "m_clientInfo.area = %s\r\n", m_clientInfo.area  );

	if ( m_clientInfo.area != NULL )
	{
		in_addr in ;
		in.s_addr = htonl( m_clientInfo.ip );
		//printf("client_ip = %s areaname = %s\n",inet_ntoa ( in ) , ip_area );
		//printf("%u ,client_ip = %s areaname = %s \n",m_clientInfo.ip ,inet_ntoa ( in ) , m_clientInfo.area );
		m_player->set_province( m_clientInfo.area);
	}
	else
	{
		//printf("find area name faild\n");
		m_clientInfo.area = (char*)m_player->get_province();
		m_player->set_province( m_clientInfo.area);
	}
}

void FrontClientHandler::postRegisterQueue( LocalInfo & local , const char * user_name , const char * user_pwd , bool fasted )
{
	DWORD client_ip			=  htonl( get_address().get_long_addr() );
	m_clientInfo.area		= TIPDataBase::instance()->find_area_name( client_ip );
	m_clientInfo.area = m_clientInfo.area == NULL ? "" : m_clientInfo.area ;

	string strImsi = local.imsi;
	string strImei = local.imei;
	string strModel = local.model;
	string externName  = local.extername;
	string strVec = local.gameversion;
	string strMac = local.macaddr;

	StreamPacketBuilder::instance()->filterSinglequotes(strImsi);
	StreamPacketBuilder::instance()->filterSinglequotes(strImei);
	StreamPacketBuilder::instance()->filterSinglequotes(strModel);
	StreamPacketBuilder::instance()->filterSinglequotes(externName);
	StreamPacketBuilder::instance()->filterSinglequotes(strVec);
	StreamPacketBuilder::instance()->filterSinglequotes(strMac);
	
	
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	req->id = 0;
	snprintf( req->sql , sizeof(req->sql) ,"call sp_register_user('%s','%s',%u,%d,%d,%d,'%s','%s','%s','%s','%s' , %u,  '%s', '%s', '%s' )",
		user_name,user_pwd,client_ip,fasted,local.flatform_type ,
		local.channel,local.version,strImsi.c_str(),strImei.c_str(),strModel.c_str(),m_clientInfo.area, local.externid, externName.c_str(),
		strVec.c_str(), strMac.c_str());
	req->client		= this ;
	req->req_type	= REQ_TYPE_REGISTER ;
	DataBaseReadThreadPool::instance()->pushQueue( req );
	WL(LL_ERROR," register:%s  \r\n", req->sql);

	

}
void FrontClientHandler::handleRegister( Packet* packet , bool fasted )
{
	StreamReader reader( packet->getData() );

	char user_name[USER_NAME_LENGTH] = {0};
	WORD tmplen = reader.get_short();
	if (tmplen >= USER_NAME_LENGTH)
		tmplen = USER_NAME_LENGTH - 1;

	memcpy(user_name, reader.get_current_ptr(), tmplen);
	reader.skip(tmplen);

	char user_pwd[PASSWORD_LEN] = {0};

	tmplen = reader.get_short();
	if (tmplen >= PASSWORD_LEN)
		tmplen = PASSWORD_LEN - 1;

	memcpy(user_pwd, reader.get_current_ptr(), tmplen);
	reader.skip(tmplen);

	//LocalInfo  local_info ;
	parse_local_info( reader ,m_localInfo );
	postRegisterQueue( m_localInfo , user_name , user_pwd , fasted );
}

void FrontClientHandler::handleRegisterResult( SQLResp * resp )
{
	if ( !resp->result  ) 
	{
		//登录错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_REGISTER , resp->result  );
		WL(LL_INFO, "register result:%d \r\n", resp->result);
		return ;
	}
	RegisterResult * r = ( RegisterResult *)resp->data ;
	if ( r->result != 0 )
	{
		//注册错误
		//用户名已绑定账号
		if ( r->result == 5 )
		{
			//StreamPacketBuilder::instance()->respError( this ,MSG_RESP_LOGIN , ERR_LOGIN_ACCOUNT_BINDED  );
			char senddata[1024] = {0};
			StreamWriter stream_wirte( senddata, sizeof(senddata) );
			stream_wirte.add_byte( RESULT_FAILD );
			stream_wirte.add_int( ERR_LOGIN_ACCOUNT_BINDED );
			stream_wirte.add_byte( r->user_name_len );
			stream_wirte.appand( r->user_name, r->user_name_len );
			sendPacket( MSG_RESP_LOGIN, stream_wirte.get_buffer(), stream_wirte.get_buffer_len() );
			
		}
		else
		{
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_REGISTER , r->result  );
		}

		WL(LL_INFO, "register result:%d \r\n", r->result);
		return ;
	}

	if ( r->is_new ){
		writeRegiLog( htonl( get_address().get_long_addr()) , r->userId , m_localInfo );
	}
		
	StreamPacketBuilder::instance()->respRegister( this , r );
}
void FrontClientHandler::handleEmailList( Packet* packet )
{
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_get_email(%u)",m_player->get_user_id() );
	req->client		= this ;
	req->req_type	= REQ_TYPE_EMAIL_LIST ;
	//printf( "player = %u req email list sql=%s\n",m_player->get_user_id(),req->sql );
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::handleEmailListResult( SQLResp * resp )
{
	this->sendPacket( MSG_RESP_EMAIL_LIST , resp->data , resp->len );
}

void FrontClientHandler::writeRegiLog( DWORD ip , DWORD user_id , LocalInfo & local_info )
{
	const char * province = Config::instance()->get_province( m_clientInfo.area );
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call p_write_register_log(%u,%u,%d,%d,'%s','%s','%s','%s','%s','%s')",
		user_id , ip , local_info.flatform_type,local_info.channel,
		local_info.version,
		local_info.imsi,
		local_info.imei,
		local_info.model,
		m_clientInfo.area,
		province);
	DataBaseCommitThread::instance()->push( req );
}

void FrontClientHandler::writeLoginLog( DWORD ip , DWORD user_id , LocalInfo & local_info , int & persent_gold )
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call p_new_login_log(%u,%u,%d,%d,'%s','%s','%s','%s','%s',%d,'%s')",
		user_id , ip , local_info.flatform_type,local_info.channel,
		local_info.version,
		local_info.imsi,
		local_info.imei,
		local_info.model,
		m_clientInfo.area,persent_gold,
		local_info.gameversion
		);
	DataBaseCommitThread::instance()->push( req );
}

void FrontClientHandler::handleHongbaoTaskList( Packet* packet )
{
	if ( m_player == NULL ) return ;

	if (m_player->getUserInfo().today_login == 1)
	{
		m_player->SetLoadHongbaoTasks(true);
	}

	if (m_player->IsLoadHongbaoTasks()) {
		m_player->SendHongbaoTasksToClient();
		return;
	}

	RequestHongbaoTaskListFromDB();
}

void			FrontClientHandler::handleHongbaoNum(Packet* packet)
{
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_HONGBAO_NUM , this );
	snprintf( req->sql , sizeof(req->sql) ,
		"select hongbao from user_hongbao_info where user_id=%u", m_player->get_user_id() );
	WL(LL_DEV ,"player = %u req hongbao num\n",m_player->get_user_id());
	DataBasePacketDataThread::instance()->push( req );
}
void			FrontClientHandler::handleFreeHongbao(Packet* packet)
{
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call p_free_hongbao(%u)",m_player->get_user_id() );
	req->client		= this ;
	req->req_type	= REQ_TYPE_FREE_HONGBAO ;
	WL(LL_DEV ,"player = %u req free hongbao\n",m_player->get_user_id());
	DataBasePacketDataThread::instance()->push( req );
}
void			FrontClientHandler::handleOpenHongbao(Packet* packet)
{
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	int rand_val;
	rand_val = rand() % 10000;
	snprintf( req->sql , sizeof(req->sql) ,"call p_open_hongbao(%u, %u)",m_player->get_user_id(), rand_val );
	req->client		= this ;
	req->req_type	= REQ_TYPE_OPEN_HONGBAO ;
	WL(LL_DEV ,"player = %u req open hongbao %u\n",m_player->get_user_id(), rand_val);
	DataBasePacketDataThread::instance()->push( req );	
}
void			FrontClientHandler::handleHongbaoHistory(Packet* packet)
{
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_HONGBAO_HISTORY , this );
	snprintf( req->sql , sizeof(req->sql) ,
		"select UNIX_TIMESTAMP(`oper_time`) AS `oper_time`, `reward_type`, `reward_value`, `already_send` from user_open_hongbao_log where user_id=%u", m_player->get_user_id() );
	WL(LL_DEV ,"player = %u req hongbao history\n",m_player->get_user_id());
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::RequestHongbaoTaskListFromDB()
{	
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"select `task_id`, `task_status`, `task_value`, `finishtime` from user_hongbao_task where user_id = %u",m_player->get_user_id() );
	req->client		= this ;
	req->req_type	= REQ_TYPE_HONGBAO_TASK_LIST ;
	//printf( "zq req->sql: %s\n",req->sql );
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::handleTaskList( Packet* packet )
{
	if ( m_player == NULL ) return ;

	if (m_player->IsLoadTasks()) {
		m_player->SendTasksToClient();
		return;
	}

	RequestTaskListFromDB();
}

void FrontClientHandler::RequestTaskListFromDB()
{
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call p_get_tasks(%u)",m_player->get_user_id() );
	req->client		= this ;
	req->req_type	= REQ_TYPE_TASK_LIST ;
	//printf( "zq req->sql: %s\n",req->sql );
	DataBasePacketDataThread::instance()->push( req );
}


void FrontClientHandler::handleUpdateTask( TaskInfo * pTask, int awardgold )
{
	if ( awardgold == 0 )
	{
		//更新任务状态
		SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		req->id = m_player->get_user_id();
		snprintf( req->sql , sizeof(req->sql) ,"call p_finish_task(%u, %d, %d)",m_player->get_user_id(), pTask->taskid, pTask->finishtime );
		//printf( "handleUpdateTask req->sql = %s\r\n", req->sql );
		req->client		= NULL ;
		req->req_type	= REQ_TYPE_EXECUTE_COMMOND;
		DataBaseReadThreadPool::instance()->pushQueue( req );
	}
	else
	{
		SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		req->id = m_player->get_user_id();
		snprintf( req->sql , sizeof(req->sql) ,"call p_save_task(%u, %d, %d, %d)",m_player->get_user_id(), pTask->taskid, pTask->taskstatus, awardgold );
		//printf( "handleUpdateTask req->sql = %s\r\n", req->sql );
		req->client		= this ;
		req->req_type	= REQ_TYPE_TASK_REWARD;
		DataBaseReadThreadPool::instance()->pushQueue( req );
	}
}

void FrontClientHandler::handleUpdateHongbaoTask( TaskInfo * pTask )
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call p_award_hongbao_task(%u, %d)",m_player->get_user_id(), pTask->taskid );
		//printf( "handleUpdateTask req->sql = %s\r\n", req->sql );
	WL(LL_DEV ,"%s req->sql = %s\r\n", __FUNCTION__, req->sql );
	req->client		= this ;
	req->req_type	= REQ_TYPE_HONGBAO_TASK_REWARD;
	DataBaseReadThreadPool::instance()->pushQueue( req );
	
		// TODO: 
	// if ( awardgold == 0 )
	// {
	// 	//更新任务状态
	// 	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	// 	req->id = m_player->get_user_id();
	// 	snprintf( req->sql , sizeof(req->sql) ,"call p_finish_task(%u, %d, %d)",m_player->get_user_id(), pTask->taskid, pTask->finishtime );
	// 	//printf( "handleUpdateTask req->sql = %s\r\n", req->sql );
	// 	req->client		= NULL ;
	// 	req->req_type	= REQ_TYPE_EXECUTE_COMMOND;
	// 	DataBaseReadThreadPool::instance()->pushQueue( req );
	// }
	// else
	// {
	// 	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	// 	req->id = m_player->get_user_id();
	// 	snprintf( req->sql , sizeof(req->sql) ,"call p_save_task(%u, %d, %d, %d)",m_player->get_user_id(), pTask->taskid, pTask->taskstatus, awardgold );
	// 	//printf( "handleUpdateTask req->sql = %s\r\n", req->sql );
	// 	req->client		= this ;
	// 	req->req_type	= REQ_TYPE_HONGBAO_TASK_REWARD;
	// 	DataBaseReadThreadPool::instance()->pushQueue( req );
	// }
}
void FrontClientHandler::handleAddFriend(DWORD srcPlayerid, DWORD desPlayerid, long long curtime)
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_friend_add(%u, %u, %llu)", srcPlayerid, desPlayerid, curtime );
	req->client		= this ;
	req->req_type	= REQ_TYPE_FRIEND_ADD;
	//WL(LL_DEV ,"player = %u update task sql=%s\n",m_player->get_user_id(),req->sql);
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::handleAddFriendMsg(DWORD srcPlayerid, DWORD desPlayerid, long long curtime, WORD msglen, char * chatmsg)
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_friend_add_msg(%u, %u, %llu, %d, '%s')", srcPlayerid, desPlayerid, curtime, msglen, chatmsg );
	req->client		= this ;
	req->req_type	= REQ_TYPE_FRIEND_ADD_MSG;
	//WL(LL_DEV ,"player = %u update task sql=%s\n",m_player->get_user_id(),req->sql);
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::handleDeleteFriend(DWORD srcPlayerid, DWORD desPlayerid)
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_friend_delete(%u, %u)", srcPlayerid, desPlayerid );
	req->client		= this ;
	req->req_type	= REQ_TYPE_FRIEND_DELETE;
	//WL(LL_DEV ,"player = %u update task sql=%s\n",m_player->get_user_id(),req->sql);
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::handleGiveGift( DWORD srcPlayerid, int giftid, DWORD desPlayerid,  int giftgold )
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	req->id = srcPlayerid;
	snprintf( req->sql , sizeof(req->sql) ,"call sp_friend_give_gift(%u, %d, %u, %d)", srcPlayerid, giftid, desPlayerid, giftgold );
	//printf( "req->sql = %s\r\n", req->sql );
	req->client		= this;
	req->req_type	= REQ_TYPE_FRIEND_GIVE_GFIT;
	//DataBasePacketDataThread::instance()->push( req );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleGiftAddFriend( DWORD srcPlayerid, DWORD desPlayer, DWORD giftid, DWORD giftgold, int giftnum )
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	req->id = srcPlayerid;
	snprintf( req->sql , sizeof(req->sql) ,"call sp_friend_add_by_gift( %u, %d, %d, %d, %d )", srcPlayerid, desPlayer, giftid, giftgold, giftnum );
	//printf( "zq req->sql = %s \r\n", req->sql );
	req->client		= this;
	req->req_type	= REQ_TYPE_FRIEND_ADD_BY_GFIT;
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::DeleteEnemy(DWORD playerid)
{
	if (m_player == NULL)
		return;

	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_enemy_delete(%u, %u)", m_player->get_user_id(), playerid);
	req->client		= this;
	req->req_type	= REQ_TYPE_ENEMY_DELETE;
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::UpdateOrAddEnemy(int is_update, FriendInfo * pEnemy)
{
	if (m_player == NULL)
		return;

	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_enemy_update_or_add(%u, %u, %d, %llu, %d)", 
		m_player->get_user_id(), pEnemy->userid, pEnemy->golds, pEnemy->add_time, is_update);
	//printf( "zq UpdateOrAddEnemy sql: %s\r\n", req->sql );
	req->client		= this;
	req->req_type	= REQ_TYPE_ENEMY_UPDATE_OR_ADD;
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::GetEnemyFromDB(DWORD playerid)
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_enemy_get_list(%u)", playerid);
	//printf( "zq GetEnemyFromDB sql:%s\r\n", req->sql );
	req->client		= this;
	req->req_type	= REQ_TYPE_ENEMY_GET_LIST;
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::AddMail(DWORD playerid, int mail_type, const char * msgdata)
{
	//char desBuff[1024] = {0};
	//if (CsvDataMgr::instance()->gb2312toutf8((char *)msgdata, strlen(msgdata), desBuff, sizeof(desBuff)) != 0) {
	//	WL(LL_INFO ,"AddMail msgdata =%s,  desBuff = %s \n" ,msgdata, desBuff);
	//	return;
	//}
	//printf( "zq addmail msgdata = %s \r\n", msgdata );
	FrontClientHandler * ower_handler = ActiveConnsList::instance()->find( playerid );
	if ( ower_handler ) 
	{
		//if (CsvDataMgr::instance()->gb2312toutf8((char *)msgdata, strlen(msgdata), desBuff, sizeof(desBuff)) == 0) {
			char senddata[1024];
			StreamWriter stream_out(senddata, sizeof(senddata));
			stream_out.add_byte( mail_type );
			int msglen = strlen(msgdata);
			stream_out.add_short(msglen);
			stream_out.appand(msgdata, msglen);
			ower_handler->sendPacket(MSG_NOTIFY_ADD_EMAIL, senddata, stream_out.get_buffer_len());
		//}
	}
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call p_email_add(%u, '%s', %d)", playerid, msgdata, mail_type );
	req->client		= this ;
	req->req_type	= REQ_TYPE_ADD_EMAIL ;
	//printf( "AddMail task sql=%s\n" ,req->sql );
	DataBasePacketDataThread::instance()->push( req );
}

void			FrontClientHandler::handleHongbaoNumResult(SQLResp * resp)
{
	if (!m_player)
		return;

	if (resp->data == NULL || resp->len < 4) {
		return;
	}

	StreamReader reader( resp->data );
	int	tasknum	= reader.get_int();
	
	u8_t  taskdata [ 8192 ]	;
	StreamWriter stream_out(taskdata, sizeof(taskdata));

	stream_out.add_int( tasknum );
	sendPacket( MSG_RESP_HONGBAO_NUM, taskdata, stream_out.get_buffer_len() );
}
void			FrontClientHandler::handleFreeHongbaoResult(SQLResp * resp)
{
	if (!m_player)
		return;
	if (resp->data == NULL || resp->len < 4) {
		return;
	}

	StreamReader reader( resp->data );
	int	tasknum	= reader.get_int();
	
	u8_t  taskdata [ 8192 ]	;
	StreamWriter stream_out(taskdata, sizeof(taskdata));

	stream_out.add_int( tasknum );
	sendPacket( MSG_RESP_FREE_HONGBAO, taskdata, stream_out.get_buffer_len() );
}
void			FrontClientHandler::handleOpenHongbaoResult(SQLResp * resp)
{
	if (!m_player)
		return;
	if (resp->data == NULL || resp->len < 12) {
		return;
	}

	StreamReader reader( resp->data );
	int	result	= reader.get_int();
	int	type	= reader.get_int();
	int	value	= reader.get_int();	
	
	u8_t  taskdata [ 8192 ]	;
	StreamWriter stream_out(taskdata, sizeof(taskdata));

	stream_out.add_int( result );
	stream_out.add_int( type );
	stream_out.add_int( value );	
	sendPacket( MSG_RESP_OPEN_HONGBAO, taskdata, stream_out.get_buffer_len() );

	char broadcast_buf[512];
	int broadcast_len = 0;
	switch (type)
	{
		case 1:
			if (value >= 10000)
				broadcast_len = sprintf(broadcast_buf, "恭喜玩家%s，通过拆红包活动，获取了%d金币", m_player->get_nick_name(), value) + 1;
			m_player->add_user_gold(value);
			StreamPacketBuilder::instance()->notifyUpdatePlayerGold( m_player->getTable() , m_player ) ;; //通知更新金币  
			break;
		case 2:
			broadcast_len = sprintf(broadcast_buf, "恭喜玩家%s，通过拆红包活动，获取了话费", m_player->get_nick_name()) + 1;			
			break;
		case 3:
			broadcast_len = sprintf(broadcast_buf, "恭喜玩家%s，通过拆红包活动，获取了汽车", m_player->get_nick_name()) + 1;						
			break;
		case 4:
			broadcast_len = sprintf(broadcast_buf, "恭喜玩家%s，通过拆红包活动，获取了飞机", m_player->get_nick_name()) + 1;
			break;
		case 5:
			broadcast_len = sprintf(broadcast_buf, "恭喜玩家%s，通过拆红包活动，获取了奖券", m_player->get_nick_name()) + 1;			
			break;
		case 6:
		{
			broadcast_len = sprintf(broadcast_buf, "恭喜玩家%s，通过拆红包活动，获取了%d钻石", m_player->get_nick_name(), value) + 1;
			m_player->set_diamond(m_player->get_diamond() + value);
				//下发给用户金币变化			
			char senddata[128] = {0};
			StreamWriter stream_write( senddata, sizeof(senddata) );
			stream_write.add_byte( 1 );
			stream_write.add_int64( m_player->get_user_gold() );
			stream_write.add_int( m_player->get_diamond() );
			stream_write.add_int( m_player->get_user_score()->ticket);
			stream_write.add_byte( 1 );//类型  1推荐
			sendPacket( MSG_RSP_UPDATE_WEALTH, stream_write.get_buffer(), stream_write.get_buffer_len() );
		}	
		break;
		case 7:
			break;
	}
	if (broadcast_len != 0)
	{
		StreamWriter writer(taskdata, sizeof(taskdata));
		writer.add_short(broadcast_len);
		writer.appand  ( broadcast_buf, broadcast_len);
		StreamPacketBuilder::instance()->handleBroadcast(MSG_RESP_HONGBAO_REWARD_BROADCAST,(u8_t *)writer.get_buffer(), writer.get_buffer_len());
	}
}
void			FrontClientHandler::handleHongbaoHistoryResult(SQLResp * resp)
{
	if (!m_player)
		return;
	if (resp->data == NULL || resp->len < 2) {
		return;
	}

	StreamReader reader( resp->data );
	WORD	tasknum	= reader.get_short();
	
	u8_t  taskdata [ 8192 ]	;
	StreamWriter stream_out(taskdata, sizeof(taskdata));

	stream_out.add_word( tasknum );

	for (WORD i = 0; i < tasknum; ++i) {
		int type = reader.get_int();
		int value = reader.get_int();
		BYTE already_send = reader.get_byte();
		int date = reader.get_int();
		stream_out.add_int( type);
		stream_out.add_int( value);
		stream_out.add_byte( already_send);
		stream_out.add_int( date);
	}
	
	sendPacket( MSG_RESP_HONGBAO_HISTORY, taskdata, stream_out.get_buffer_len() );
}

void FrontClientHandler::handleHongbaoTaskListResult( SQLResp * resp )
{
	if (!m_player)
		return;

	m_player->InitHongbaoTasks(resp->data , resp->len);
	m_player->SendHongbaoTasksToClient();
}

void FrontClientHandler::handleTaskListResult( SQLResp * resp )
{
	if (!m_player)
		return;

	m_player->InitTasks(resp->data , resp->len);
	m_player->SendTasksToClient();
}

void FrontClientHandler::handleExchangeRecord( Packet* packet )
{
	if ( m_player == NULL ) return ;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_EXCHAGE_RECORD , this );
	snprintf( req->sql , sizeof(req->sql) ,
		"select a.receive,a.opera_date,a.receive_date,a.total_ticket,b.exch_name \
		from exch_log a , exch_product b where a.commodity_id = b.exch_id and user_id=%u ORDER BY a.opera_date DESC ",
		m_player->get_user_id() );
	WL(LL_DEV ,"player = %u req exchange record list sql=%s\n",m_player->get_user_id(),req->sql);
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::handleExchangeRecordResult( SQLResp * resp )
{
	this->sendPacket( MSG_RESP_EXCH_RECORD , resp->data , resp->len );
}

//
void FrontClientHandler::handleReceiveTaskBonus( Packet* packet )
{
	if ( m_player == NULL ) return ;
	StreamReader reader( packet->getData() );
	int task_id  = reader.get_int() ;
	TaskInfo * taskinfo = m_player->GetTask(task_id);
	PLAYER_TASK_STRUCT * ptask = Config::instance()->GetTask(task_id);
	BYTE resultnum = RESULT_OK;

	if (taskinfo == NULL || ptask == NULL)
	{
		//printf( "zq task_id = %d taskinfo = %x ptask = %x", task_id, taskinfo, ptask );
		resultnum = ERR_NOT_FOUND_TASK;
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_RECV_TASK_BONUS , ERR_NOT_FOUND_TASK  );
		return;
	}

	//任务没有完成不处理
	if ( taskinfo->taskstatus != TASK_STATUS_CANFINISH )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_RECV_TASK_BONUS , ERR_NOT_FOUND_TASK  );
		return;
	}
	handleUpdateTask( taskinfo, ptask->task_reward );
}
void FrontClientHandler::handleReceiveHongbaoTaskBonus( Packet* packet )
{
	if ( m_player == NULL ) return ;
	StreamReader reader( packet->getData() );
	int task_id  = reader.get_int() ;
	TaskInfo * taskinfo = m_player->GetHongbaoTask(task_id);
	PLAYER_HONGBAO_TASK_STRUCT * ptask = Config::instance()->GetHongbaoTask(task_id);
	BYTE resultnum = RESULT_OK;

	if (taskinfo == NULL || ptask == NULL)
	{
		//printf( "zq task_id = %d taskinfo = %x ptask = %x", task_id, taskinfo, ptask );
		resultnum = ERR_NOT_FOUND_TASK;
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_RECV_HONGBAO_TASK_BONUS , ERR_NOT_FOUND_TASK  );
		return;
	}

	//任务没有完成不处理
	if ( taskinfo->taskstatus != TASK_STATUS_CANFINISH )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_RECV_HONGBAO_TASK_BONUS , ERR_NOT_FOUND_TASK  );
		return;
	}
	handleUpdateHongbaoTask( taskinfo );
}
void FrontClientHandler::handleReceiveTaskBonusResult( SQLResp * resp )
{
	//printf( "handleReceiveTaskBonusResult======\r\n" );
	if ( !resp->result || m_player == NULL ) 
	{
		//
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_RECV_TASK_BONUS , ERR_SYSTEM  );
		return ;
	}
	TaskBonusResult * r = ( TaskBonusResult *)resp->data ;
	if ( r->result == 0 )
	{
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_RECV_TASK_BONUS , ERR_SYSTEM );
		return  ;
	}
	INT64 balance = m_player->get_user_gold();
	m_player->set_user_gold( r->usergold);
	char senddata[1024] = {0};
	StreamWriter stream_out(senddata, sizeof(senddata));
	stream_out.add_byte( RESULT_OK );
	stream_out.add_int64(m_player->get_user_gold());
	sendPacket( MSG_RESP_RECV_TASK_BONUS , senddata , stream_out.get_buffer_len() );
}
void FrontClientHandler::handleReceiveHongbaoTaskBonusResult( SQLResp * resp )
{
	//printf( "handleReceiveTaskBonusResult======\r\n" );
	if ( !resp->result || m_player == NULL ) 
	{
		//
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_RECV_HONGBAO_TASK_BONUS , ERR_SYSTEM  );
		return ;
	}
	HongbaoTaskBonusResult * r = ( HongbaoTaskBonusResult *)resp->data ;
	if ( r->result == 0 )
	{
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_RECV_HONGBAO_TASK_BONUS , ERR_SYSTEM );
		return  ;
	}
		//INT64 balance = m_player->get_user_gold();
	m_player->set_user_gold( r->gold);
	m_player->set_diamond( r->diamond);
	m_player->set_hongbao( r->hongbao);
	TaskInfo * taskinfo = m_player->GetHongbaoTask(r->task_id);
	if (taskinfo)
	{
		WL(LL_DEV ,"%s: player = %u task %u finished\n", __FUNCTION__, m_player->get_user_id(), r->task_id);
		taskinfo->taskstatus = TASK_STATUS_FINISHED;
	}
	else
	{
		WL(LL_ERROR ,"%s: player = %u task %u can not find\n", __FUNCTION__, m_player->get_user_id(), r->task_id);		
	}
	
	char senddata[1024] = {0};
	StreamWriter stream_out(senddata, sizeof(senddata));
	stream_out.add_byte( RESULT_OK );
	stream_out.add_int64(m_player->get_user_gold());
	sendPacket( MSG_RESP_RECV_HONGBAO_TASK_BONUS , senddata , stream_out.get_buffer_len() );
}
void FrontClientHandler::handleRecommendAwardResult( SQLResp * resp )
{
	if ( !resp->result || m_player == NULL ) 
	{
		//登录错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_RECOMMEND_AWARD , ERR_SYSTEM  );
		return ;
	}
	RecommendAwardResult * r = ( RecommendAwardResult *)resp->data ;

	if ( r->status == 2 ) // 推荐码找不到用户ID
	{
		WL(LL_WARNING ,"not found referee = %u\n",r->referee_code );
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_RECOMMEND_AWARD , ERR_NOT_FOUND_REFEREE_CODE );
		
	}else if ( r->status == 1 ){
		//已经操作过了
		WL(LL_WARNING ,"user_id = %u aleady get recommend award \n",m_player->get_user_id() );
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_RECOMMEND_AWARD , ERR_REPEAT_OTAIN_AWARD );
		
	}else{

		WL(LL_INFO ,"user_id = %u referee_code = %d novice_award = %d award = %d balance=%lld \n",
			m_player->get_user_id(), r->referee_code ,r->novice_award ,r->award ,m_player->get_user_gold());
		m_player->set_user_gold( m_player->get_user_gold() + r->novice_award) ;
		m_player->add_user_ticket( r->newer_ticket );
		StreamPacketBuilder::instance()->recommendAwardResult( m_player );
		//查找推荐人
		FrontClientHandler * handler = ActiveConnsList::instance()->find( r->referee_code );
		if ( handler )
		{
			Player * player  = handler->getPlayer();
			if ( player != NULL )
			{
				player->set_user_gold( player->get_user_gold() + r->award) ;
				player->add_user_ticket( r->ticket_count );
				StreamPacketBuilder::instance()->notifyRecommendAward( player , r );
			}
		}
		
	}
}

void FrontClientHandler::handleRecommendAward( Packet* packet )
{
	if ( m_player == NULL ) return ;
	StreamReader reader( packet->getData() );
	//推荐码
	int referee_code				= reader.get_uint() ;;
	
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_RECOMMEND_AWARD , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_recommend_award(%u,'%s',%u,%u)",
		m_player->get_user_id() , m_player->get_user_name() ,referee_code, m_player->get_user_gold());
	WL(LL_DEV ,"player = %u req RecommendAward sql=%s\n",m_player->get_user_id(), req->sql);
	DataBaseReadThreadPool::instance()->pushQueue( req );
}


void FrontClientHandler::handleOnlineRewardResult( SQLResp * resp )
{
#if 0
	printf( "zq ========= handleOnlineRewardResult resp = %x\r\n", resp );
	if ( !resp->result || m_player == NULL ) 
	{
		//
		StreamPacketBuilder::instance()->respError( this ,MSG_REQ_REWARD_COIN , ERR_SYSTEM  );
		return ;
	}

	OnlineRewardResult * r = ( OnlineRewardResult *)resp->data ;
	printf( "zq ========= handleOnlineRewardResult r->result = %d m_player=%x\r\n", r->result, m_player );
	if ( r->result > 0 ) //成功
	{
		if ( m_player )
		{
		}
	}
	else
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_REQ_REWARD_COIN , ERR_SYSTEM  );
	}
#endif
}

void FrontClientHandler::handleExchangeProduct( Packet* packet )
{
	if ( m_player == NULL ) return ;
	StreamReader reader( packet->getData() );
	int prod_id				= reader.get_uint() ;
	//联电话
	char * phone			= reader.get_current_ptr();
	BYTE len				= strlen( phone ) + 1 ;
	reader.skip( len );
	//邮编
	char * zip_code			=  reader.get_current_ptr();
	len						= strlen( zip_code ) + 1 ;
	reader.skip( len );
	//收件人
	char * consignee		=  reader.get_current_ptr();
	len						= strlen( consignee ) + 1 ;
	reader.skip( len );
	//收件人地址
	char * consignee_addr	=  reader.get_current_ptr();
	ExchCommodityItem * item =  ExchCommodityManager::instance()->exists_commodity( prod_id ) ;
	if ( item == NULL )
	{
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_EXCH_COMMODITY , ERR_NOT_FOUND_COMMODITY );
		WL(LL_WARNING,"not found prod = %d\n",prod_id);
		return  ;
	}
	if ( item->ticket > m_player->get_user_score()->ticket )
	{
		WL(LL_WARNING,"%d not enungh ticket %d\n",item->ticket , m_player->get_user_score()->ticket );
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_EXCH_COMMODITY , ERR_NOT_ENUNGH_TICKET );
		return  ;
	}
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_EXCHAGE_PRODUCT , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_exch_commdity(%u,%d,%d,'%s','%s','%s','%s')",
		m_player->get_user_id() , prod_id , item->ticket,phone , zip_code , consignee , consignee_addr );
	WL(LL_DEV ,"player =%d req exchage commdodity sql=%s\n",m_player->get_user_id(),req->sql);
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleExchangeProductResult( SQLResp * resp )
{
	if ( !resp->result || m_player == NULL ) 
	{
		//登录错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_EXCH_COMMODITY , ERR_SYSTEM  );
		return ;
	}
	ExchangeProductResult * r = ( ExchangeProductResult *)resp->data ;
	if ( r->result > 0  )
	{
		DWORD balance = m_player->get_user_score()->ticket ;
		WL(LL_INFO ,"user_id = %u ticket_balance = %d exch_ticket = %d \n",
			m_player->get_user_id(), balance ,r->ticket);
		m_player->set_user_ticket( balance - r->ticket ) ;
	}
	StreamPacketBuilder::instance()->exchangeProductResult( m_player );
}

void FrontClientHandler::handleUpdateUserInfo( Packet* packet )
{
	if ( m_player == NULL ) return ;
	
	StreamReader reader( packet->getData() );
	DWORD		user_id		= reader.get_uint() ;
	BYTE		sex			= reader.get_byte();

	BYTE  length			= 0 ;

	//昵称
	const char * nick_name	= reader.get_current_ptr();
	length					= S_STRLEN( nick_name ) ;
	//printf( "zq handleUpdateUserInfo nick_name = -%s-  len = %d  old nick:%s\r\n", nick_name, length, m_player->get_nick_name() );
	if ( length == 1 )
	{
		nick_name = m_player->get_nick_name();
	}
	reader.skip( length );
	//printf( "zq handleUpdateUserInfo 2 nick_name = -%s-  len = %d  old nick:%s\r\n", nick_name, length, m_player->get_nick_name() );
	//修改签名 
	char * user_sign	= reader.get_current_ptr();
	length					= S_STRLEN( user_sign ) ;
	if ( length > SIGN_MAX_LEN )
	{
		user_sign[SIGN_MAX_LEN - 1] = '\0';
	}
	if ( length == 1 )
	{
		user_sign = m_player->get_char_sign();
	}
	reader.skip( length );

	//密码
	char *		user_pwd	= reader.get_current_ptr();
	length					= S_STRLEN( user_pwd ) ;
	BYTE		password_len = length ;
	if ( length > PASSWORD_LEN )
	{
		user_pwd[PASSWORD_LEN - 1] = '\0';
	}
	reader.skip( length );

	//联系方式
	char *		contact		= reader.get_current_ptr();
	length					= S_STRLEN( contact ) ;
	if ( length > CONTACT_LENGTH )
	{
		contact [ CONTACT_LENGTH - 1 ] = '\0';
	}
	if ( length == 1 )
	{
		contact = m_player->getUserInfo().getContack();
	}
	reader.skip( length );

	//常住地址 -- 用户省份
	char *		user_addr		= reader.get_current_ptr();
	length					= S_STRLEN( user_addr ) ;
	if ( length > PROVICE_LENGTH ) 
	{
		user_addr [ PROVICE_LENGTH - 1 ] = '\0';
	}
	if ( length == 1 )
	{
		user_addr = m_player->get_province();
	}
	reader.skip( length );

	BYTE modifytype = reader.get_byte();
	
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_UPDATE_USER_INFO, this );
	req->id = m_player->get_user_id();
	snprintf(req->sql , sizeof(req->sql) ,"call sp_updateUserInfo(%u,%d,'%s','%s','%s','%s','%s','%s')",
		m_player->get_user_id() , sex , "" , user_pwd ,nick_name ,contact, user_sign,  user_addr  );
		//printf( "zq handleUpdateUserInfo req->sql=%s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleUpdateUserInfoEx()
{
	if ( m_player == NULL ) return ;
	UserInfo & refinfo = m_player->getUserInfo();

	int max_card_num = refinfo.max_card[0]+refinfo.max_card[1]*100+refinfo.max_card[2]*10000;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_UPDATE_USER_INFO_EX, this );
	req->id = m_player->get_user_id();
	snprintf(req->sql , sizeof(req->sql) ,"call sp_updateUserInfoEx(%u,%d,%d,%d,%lld,%u, %d,%d,%d,%d,%d,%d,%d,%d,%d,%u ,%u,%u,%u,%u,%u, %d)",
		m_player->get_user_id() , refinfo.today_get_help_count , refinfo.tody_get_login_box_count , 
		refinfo.today_get_online_count ,refinfo.user_score.gold, refinfo.last_login_time,
		refinfo.total_win_counts, refinfo.total_primary_win_counts, refinfo.total_middle_win_counts, refinfo.total_high_win_counts,
		refinfo.today_game_counts, refinfo.today_win_counts, refinfo.total_pay_num, refinfo.total_use_laba_counts,max_card_num,
		refinfo.user_score.diamond, refinfo.flower, refinfo.aggs, refinfo.car, refinfo.villa, refinfo.yacht,
		refinfo.tiger_raward_pool);
	//printf( "handleUpdateUserInfoEx req->sql: %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleUpdateUserInfoResult( SQLResp * resp )
{
	if ( !resp->result || m_player == NULL ) 
	{
		//登录错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_UPDATE_USER , ERR_SYSTEM  );
		return ;
	}
	UpdateUserInfoResult * r = ( UpdateUserInfoResult *)resp->data ;
	if ( r->result > 0  )
	{
		m_player->set_user_name( r->username );
		m_player->set_nick_name( r->nickname );
		m_player->set_sex( r->sex );
		m_player->set_char_sign( r->charsign );
		m_player->set_province( r->province );
		m_player->set_contact( r->contact );
		//printf( "zq r->charsign = %s\r\n", r->charsign );
		StreamPacketBuilder::instance()->respOk( this , MSG_RESP_UPDATE_USER ) ;
	}
	else
	{
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_UPDATE_USER , ERR_EXITS_USERNAME ) ;
	}
	
}

void FrontClientHandler::handleCreateOrder( Packet* packet )
{
	if ( m_player == NULL ) return ;
	StreamReader reader( packet->getData() );
	DWORD	payment		= reader.get_uint();
	int		prod_id		= reader.get_int();
	BYTE	prod_type	= reader.get_byte();
	LocalInfo  * local_info = &m_localInfo;

	char charge_id [ 16 ] = { 0 };
	static	BYTE seq		= 1 ;
	struct timeval tv ;
	struct tm tmNow;
	gettimeofday(&tv,NULL);
	localtime_r(&tv.tv_sec ,&tmNow );
	BYTE len = snprintf( charge_id , sizeof(charge_id) ,"%02d%02d%02d%02d%02d%02d%03d",
		tmNow.tm_year - 100 ,
		tmNow.tm_mon + 1 ,
		tmNow.tm_mday,
		tmNow.tm_hour,
		tmNow.tm_min,
		tmNow.tm_sec ,
		seq ++);
	DWORD client_ip			=  htonl( get_address().get_long_addr() );
	const char * provice	=  TIPDataBase::instance()->find_area_name( client_ip );
	if ( provice != NULL )
	{
		in_addr in ;
		in.s_addr = htonl( client_ip );
		//printf("%u ,client_ip = %s areaname = %s \n",client_ip ,inet_ntoa ( in ) , provice );
	}else{
		provice = "";
	}
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_CREATE_ORDER , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_create_order(%u,'%s',%u,%d,%d,%u,%d,'%s','%s','%s' ,'%s','%s')",
		m_player->get_user_id() ,charge_id ,payment ,prod_id,prod_type,client_ip ,local_info->channel ,
		local_info->imsi , local_info->imei , local_info->model , m_player->get_province() ,provice ); 

	//WL(LL_DEV ,"player =%d req create order sql=%s\n",m_player->get_user_id(),req->sql);
	DataBaseReadThreadPool::instance()->pushQueue( req );
	//StreamPacketBuilder::instance()->handleCreateOrder( this , charge_id , len );
}
void FrontClientHandler::handleCreateOrderResult( SQLResp * resp )
{
	if ( !resp->result || m_player == NULL ) 
	{
		//没有找到
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_CREATE_CHARGE_ORDER , ERR_SYSTEM  );
		return ;
	}
	CreateOrderResult * ret = ( CreateOrderResult *)resp->data ;
	StreamPacketBuilder::instance()->handleCreateOrder( this , ret->charge_id ,ret->charge_id_len );
}
void FrontClientHandler::handleChargeInfo( Packet* packet )
{
	if ( m_player == NULL ) return ;

	StreamReader reader( packet->getData() );
	int	commodity_id	= reader.get_uint();
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_CHARGE_INFO , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_getChargeInfo(%d,%d)",m_localInfo.channel ,commodity_id );
	WL(LL_DEV ,"player =%d req charge info ch=%d commdodity=%d\n",m_player->get_user_id(),m_localInfo.channel ,commodity_id );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleChargeInfoResult( SQLResp * resp )
{
	if ( !resp->result || m_player == NULL ) 
	{
		//没有找到
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_CHARGE_INFO , ERR_NOT_FOUND_CHARGE_INFO  );
		return ;
	}
	this->sendPacket( MSG_RESP_CHARGE_INFO , resp->data , resp->len );
}

void FrontClientHandler::handleHttpNotifyChargeStatus( Packet* packet )
{
	StreamReader reader( packet->getData() );
	//支付方式类型，支付宝
	BYTE	charge_type	= reader.get_byte();
	//订单号
	char *	charge_id	= reader.get_current_ptr();
	BYTE	len			= strlen( charge_id ) + 1 ;
	reader.skip( len );
	//交易状态
	BYTE	status		= reader.get_byte();
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_HTTP_COMMIT_CHARGE_RESULT , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_finish_charge_order_type('%s',%d,%d,0)",charge_id , charge_type , status );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleHttpNotifyChargeStatusResult( SQLResp * resp )
{
	if ( !resp->result ) 
	{
		//没有找到
		//StreamPacketBuilder::instance()->respError( this ,MSG_RESP_CHARGE_INFO , ERR_NOT_FOUND_CHARGE_INFO  );
		return ;
	}
	ChargeResult * r = ( ChargeResult *)resp->data ;
	switch ( r->charge_status )
	{
	case CHARGE_STATUS_FAILD:
		WL(LL_WARNING,"charge_id = %s charge faild gold = %u status = %d\n",r->charge_id , r->gold , r->status ) ;
		//response_faild( ERR_CHARGE_RECORD , SysError::instance()->get_errmsg( ERR_CHARGE_RECORD ) );
		return;
	case CHARGE_STATUS_NOT_FOUND_ORDER:
		WL(LL_WARNING,"charge_id = %s not found gold = %u\n",r->charge_id , r->gold  ) ;
		//response_faild( ERR_CHARGE_NOT_FOUND_ORDER , SysError::instance()->get_errmsg( ERR_CHARGE_NOT_FOUND_ORDER ) );
		return;
	case CHARGE_STATUS_REPEAT_FAILD:
		WL(LL_WARNING,"charge_id = %s repeat notify and deal with faild gold = %u\n",r->charge_id , r->gold  ) ;
		//response_faild( ERR_CHARGE_REPEAT_FAILD , SysError::instance()->get_errmsg( ERR_CHARGE_REPEAT_FAILD ) );
		return;
	case CHARGE_STATUS_REPEAT_SUCC:
		WL(LL_WARNING,"charge_id = %s repeat notify  and deal with ok gold = %u\n",r->charge_id , r->gold  ) ;
		//return;
	case CHARGE_STATUS_NOT_FOUND_PROD:
		WL(LL_WARNING,"charge_id = %s not found prop gold = %u\n",r->charge_id , r->gold ) ;
		//response_faild( ERR_CHARGE_NOT_FOUND_PROD , SysError::instance()->get_errmsg( ERR_CHARGE_NOT_FOUND_PROD ) );
		return;
	case CHARGE_STATUS_SUCESSFUL:

		//是道具类型的
		if ( r->prod_type == COMMODITY_TYPE_PROP ){
			WL(LL_INFO,"charge_id = %s prod_type=%d prop_id = %d prop_count = %d ticket=%d\n",
				r->charge_id ,r->prod_type, r->prop_id , r->prop_count ,r->ticket_count ) ;
		}else{
			WL(LL_INFO,"charge_id = %s prod_type=%d exchange_gold = %d ticket=%d\n",
				r->charge_id , r->prod_type ,r->gold ,r->ticket_count ) ;
		}
	}
	FrontClientHandler * handler = ActiveConnsList::instance()->find( r->user_id );

	if ( handler && handler->getPlayer()  )
	{
		Player * player = handler->getPlayer() ;
		//是道具类型的
		if ( r->prod_type == COMMODITY_TYPE_PROP ) {
			player->set_prop_count( r->prop_id , player->get_prop_count( r->prop_id ) + r->prop_count );
		}
		else{
			player->add_user_gold( r->gold );
		}
		if ( r->present_prop > 0 )
		{
			player->set_prop_count( BROADCAST_PROD_ID , player->get_prop_count( BROADCAST_PROD_ID ) + r->present_prop );
		}

		player->add_user_ticket( r->ticket_count );
		StreamPacketBuilder::instance()->notifyChargeResult( player );
	}
}

bool FrontClientHandler::handleEnterRoom( Packet * packet )
{
	
	if ( m_player == NULL ) {
		WL(LL_WARNING,"player = %d, socket = %d req enter is null\n",m_clientInfo.client_id, get_handle() );
		return false ;
	}
	StreamReader reader ( packet->getData() );
	int room_id			= reader.get_int();
	WORD	resp_code	= packet->cmd | 0x6000;//以后不能用这种方式改消息
	int sesstionid			= 0;
	int table_id		= 0;
	BYTE is_trace		= 0;
	DWORD trace_playerid = 0;
	sesstionid	= reader.get_int();
	//printf( "packet->cmd = %d MSG_REQ_CHANGE_TABLE = %d\r\n", packet->cmd, MSG_REQ_CHANGE_TABLE  );
	if ( packet->cmd != MSG_REQ_CHANGE_TABLE )
	{
		table_id		= reader.get_int();
		is_trace		= reader.get_byte();;
		trace_playerid = reader.get_uint();
		m_player->setNoPlayTime();
	}

	//WL(LL_INFO, "nUserID:%d EnterRoom room_id:%d  table_id:%d  is_trace:%d  trace_playerid:%d  \n", m_player->get_user_id(), room_id, table_id, is_trace, trace_playerid);
	RoomDirector * roomDirector = RoomManager::instance()->findRoom( room_id ) ;
	if ( roomDirector == NULL ){
		StreamPacketBuilder::instance()->respError( this ,resp_code , ERR_NOT_FOUND_ROOM );
		WL(LL_WARNING,"player =%d room not found room_id = %d\n",m_player->get_user_id() ,room_id);
		return false;
	}
	RoomConfigItem * room_conf = roomDirector->getRoom() ;
	if ( room_conf == NULL ){
		StreamPacketBuilder::instance()->respError( this ,resp_code , ERR_NOT_FOUND_ROOM );
		WL(LL_WARNING,"player =%d room not found room_id = %d\n",m_player->get_user_id() ,room_id);
		return false;
	}

	if ( (room_conf->room_type != ROOM_TYPE_NORMAL) && (room_conf->room_type != ROOM_TYPE_BRC) && (room_conf->room_type != ROOM_TYPE_PASSWORD)  && ( room_conf->room_type != ROOM_TYPE_NIUNIU))
	{
		StreamPacketBuilder::instance()->respError( this ,resp_code , ERR_NOT_FOUND_ROOM );
		WL(LL_WARNING,"player =%d room not found room_id = %d\n",m_player->get_user_id() ,room_id);
		return false;
	}

	if(packet->cmd == MSG_REQ_CHANGE_TABLE && room_conf->room_type == ROOM_TYPE_NIUNIU && m_player->isPlaying())
	{
		printf("niuniu room in game can not change room \n");
		StreamPacketBuilder::instance()->respError( this ,resp_code , NN_ERROR_CHANGE_TABLE_LIMIT );
		return false;
	}
	TableBase * oldGame = NULL ;
	if ( m_player ) oldGame = m_player->getTable();
	if ( oldGame != NULL )
	{
		//WL(LL_INFO,"oldGame = 0x%02x player=%d addr:0x%02x  old table_id = %d  room_id = %d \n",oldGame, m_player->get_user_id(), m_player, oldGame->getTableId(), room_id);
		printf("oldGame = 0x%02x player=%d addr:0x%02x  old table_id = %d  room_id = %d \n",oldGame, m_player->get_user_id(), m_player, oldGame->getTableId(), room_id);
		oldGame->leaveTable( m_player ,MSG_REQ_CHANGE_TABLE);
	}

	if ( room_id == ROOM_CONFI_ID_BRC )
	{
		FrontClientHandler * old = CloseConnsList::instance()->find( m_player->get_user_id() ) ;
		if (old )
		{
			Player * player = old->getPlayer();
			if (player && player->getTable())
			{
				player->getTable()->leaveTable( player );
				replaceHandle( old );
				CloseConnsList::instance()->release( old ) ;
			}
		}
		if( roomDirector->GetTableByID(room_id*10000)->joinTable( m_player ) == false )
		{
			StreamPacketBuilder::instance()->respError( this ,resp_code , ERR_SYSTEM_REPAIR );
			return false;
		}
		return true;
	}

	if ( restoreScene( m_player->get_user_id()  ) )
	{
		return true ;
	}
	if ( !checkEnterRoom( room_conf ) ) return false ;
	TableBase * game = NULL ;
	//密码房进入记间
	if ( room_conf->room_type == ROOM_TYPE_PASSWORD )
	{
		return handleEnterPrivateRoom( packet ) ;
	}
	else
	{
		if (is_trace == 1 || is_trace == 2 ) {
			table_id = ActiveConnsList::instance()->GetRoomID(trace_playerid);
		}
		
		if (table_id > 0) {
			game = roomDirector->GetTableByID(table_id);
			if (game)
			{
				return game->joinTable(  m_player ) ;
			}
		}

		if ( m_player->isNormalPlayer() )
		{
			
			game = roomDirector->playerChoiceTable( oldGame , m_player );
		}
		else
		{
			game = roomDirector->robotChoiceTable( oldGame , m_player );
		}
		oldGame = m_player->getTable();
		//在游戏桌上，但没有在游戏中//先离开
		if ( oldGame != NULL ) oldGame->leaveTable( m_player );

		if ( game == NULL )
		{
			WL(LL_WARNING,"player = %u enter table faild \n", m_player->get_user_id() );
			StreamPacketBuilder::instance()->respError( this ,resp_code , ERR_FULL_ROOM );
			return false ;
		}

		return game->joinTable(  m_player ) ;
	}
}


void FrontClientHandler::handleCreatePrivateRoom( Packet * packet )
{
	if ( m_player == NULL ) return ;
	StreamReader reader ( packet->getData() );
	int room_id			 = reader.get_int();

	WORD room_name_len = reader.get_ushort();
	char room_name[128] = {0};
	int templen = room_name_len >= 127 ? 126 : room_name_len;
	memcpy(room_name, reader.get_current_ptr(), templen);

	reader.skip(room_name_len);

	WORD room_pw_len = reader.get_ushort();
	char room_pw[16] = {0};
	templen = room_pw_len >= 15 ? 14 : room_pw_len;
	memcpy(room_pw, reader.get_current_ptr(), templen);
	reader.skip(room_pw_len);

	int dizhu = reader.get_int();			// 底注
	int dingzhu = reader.get_int();			// 顶注
	int kebilunshu = reader.get_int();		// 可比轮数
	int zuidalunshu = reader.get_int() -1;		// 最大轮数
	int zuixiaoxiedai = reader.get_int();	// 最小携带
	int wait_time = reader.get_int();		// 等待时间 单位秒
	BYTE casttype = reader.get_byte();		// 消费类型  0金币 1钻石 
	WORD keep_times = reader.get_ushort();	// 持续时间

	casttype = (casttype == 1) ? 1 : 0;

	//printf( "zq create pri table   name = %s, pswd = %s, keep_times = %d \n", room_name, room_pw, keep_times );
	//printf( "zq create pri table   dizhu = %d, dingzhu = %d, kebilunshu = %d, zuidalunshu =%d \n", dizhu, dingzhu, kebilunshu, zuidalunshu );
	
	int vipctablelevel = Config::instance()->m_vip_ctablelevel;
	if ( m_player->getUserInfo().viplevel < vipctablelevel )
	{
		//printf( "zq create pri table ERROR_CREATE_TABLE_LESS_VIPLEVEL \r\n" );
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE , ERROR_CREATE_TABLE_LESS_VIPLEVEL );
		return;
	}
	DWORD* pChipsList = Config::instance()->get_chips_by_basegold(dizhu );
	if ( (dizhu*10 > dingzhu) || (zuidalunshu < 1) || (kebilunshu < 0) || (!pChipsList)  ||
		(dingzhu < 0 ) || (zuixiaoxiedai < 0) || (wait_time < 0) 
		)
	{
		//printf( "zq create pri table ERROR_CREATE_TABLE_PARAM_ERR dizhu = %d dingzhu = %d \r\n", dizhu, dingzhu );
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE , ERROR_CREATE_TABLE_PARAM_ERR );
		return;
	}

	RoomDirector * roomDirector = RoomManager::instance()->findRoom( room_id ) ;
	if ( roomDirector == NULL ){
		//printf( "zq create pri table ERROR_CREATE_TABLE_NO_ROOM \r\n" );
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE , ERROR_CREATE_TABLE_NO_ROOM );
		WL(LL_WARNING,"room not found room_id = %d\n",room_id);
		return ;
	}
	RoomConfigItem * room_conf = roomDirector->getRoom() ;
	if ( room_conf == NULL ){
		//printf( "zq create pri table ERROR_CREATE_TABLE_NO_ROOM \r\n" );
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE , ERROR_CREATE_TABLE_NO_ROOM );
		WL(LL_WARNING,"room not found room_id = %d\n",room_id);
		return ;
	}
	
	int createusegold = 0;
	int createusediamond = 0;
	Config::instance()->get_create_table_fare( createusegold, createusediamond );
	if (casttype == 1)//钻石
	{
		//printf( "diamond = %d createusediamond =%d keep_times = %d\r\n", m_player->getUserInfo().user_score.diamond, createusediamond, keep_times );
		if (m_player->getUserInfo().user_score.diamond < keep_times*createusediamond) {
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE,ERROR_CREATE_TABLE_LESS_DIAMOND );
			return;
		}
		if ( m_player->get_user_gold() < zuixiaoxiedai )
		{
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE,ERROR_CREATE_TABLE_LESS_GOLD );
			WL(LL_WARNING,"user_id = %u user gold [ %lld ] < lower gold[%u] not allow player game \n", 
				m_player->get_user_id(),m_player->get_user_gold() , room_conf->lower_limit_gold  );
			return;
		}
	}
	else {
		//printf( "gold = %d createusediamond =%d keep_times = %d\r\n", m_player->getUserInfo().user_score.gold, createusediamond, keep_times );
		if ( m_player->get_user_gold() < (zuixiaoxiedai+keep_times*createusegold) )
		{
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE,ERROR_CREATE_TABLE_LESS_GOLD );
			WL(LL_WARNING,"user_id = %u user gold [ %lld ] < lower gold[%u] not allow player game \n", 
				m_player->get_user_id(),m_player->get_user_gold() , room_conf->lower_limit_gold  );
			return;
		}
	}

	

	//房间名称
	TableBase * table = PrivateTableManager::instance()->exitsCreator( m_player->get_user_id() )  ;
	if (  table )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE, ERROR_CREATE_TABLE_OWNER_EXIST );
		return ;
	}

	if ( PrivateTableManager::instance()->exists_table( room_name )   )
	{
		//存在,创建失败
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE, ERROR_CREATE_TABLE_EXIST );
		WL(LL_WARNING,"room name = %s exists\n",room_name );
		return ;
	}
	bool found = false ;
	
	table = roomDirector->getIdleTable() ;
	if ( table == NULL )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE, ERROR_CREATE_TABLE_FULL  );
		WL(LL_WARNING,"not found empty table\n" );
		return ;
	}

	RoomConfigItem * pRoomConfig = table->getRoomConf();
	if (pRoomConfig == NULL) {
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE, ERROR_CREATE_TABLE_SYSTEM_ERR );
		return;
	}

	if ( !PrivateTableManager::instance()->appand( table ) ){
		//存在,创建失败
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_APPLY_PWD_TABLE, ERROR_CREATE_TABLE_EXIST );
		roomDirector->pushBackIndlTable( table );
		return  ;
	}

	
	pRoomConfig->guo_di = dizhu;
	pRoomConfig->cell_gold = dizhu;
	pRoomConfig->max_cell_gold = dingzhu;
	pRoomConfig->min_cmp_round = kebilunshu;
	pRoomConfig->max_round = zuidalunshu;
	pRoomConfig->lower_limit_gold = zuixiaoxiedai;
	pRoomConfig->high_limit_gold = -1;
	pRoomConfig->base_gold = pRoomConfig->guo_di;
	table->setRoomKeepTime(keep_times*3600);
	table->setRoomCreateTime(time(NULL));
	pRoomConfig->chips_code[0] = dizhu;
	pRoomConfig->chips_code[4] = dingzhu;
	for ( int i = 1; i < 4; i++ )
	{
		pRoomConfig->chips_code[i] = pChipsList[i];
	}
	if (casttype == 1)
	{
		m_player->getUserInfo().user_score.diamond -= keep_times*createusediamond;
	}
	else
	{
		m_player->set_user_gold( m_player->get_user_gold() - keep_times*createusegold);
	}
	table->setBaseGold( dizhu );
	PrivateTable * privateTable = static_cast<PrivateTable *>(table);
	privateTable->set_table_info( room_name , room_pw , dizhu , m_player->get_user_id() );
	StreamPacketBuilder::instance()->respCreatePrivateTable( m_player , table );
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_EXECUTE_COMMOND, NULL );
	req->id = m_player->get_user_id();
	//in_user_id, in_type, in_tableid, in_name, in_pwd, in_base_chips, in_max_chips, in_min_gold, in_cmp_round, in_max_round, in_operator_time, in_play_time
	snprintf( req->sql , sizeof(req->sql) ,"call SP_Create_Priv_Tables( %d, %d, %d, \'%s\', \'%s\', %d, %d, %d, %d, %d, %d, %d )",
		m_player->get_user_id(), casttype, table->getTableId(), table->getTableName() ,table->getTablePwd(), table->getBaseCoin(),dingzhu,
		zuixiaoxiedai, kebilunshu, zuidalunshu, wait_time, keep_times*3600 );
	DataBaseReadThreadPool::instance()->pushQueue( req );

}

bool FrontClientHandler::handleEnterPrivateRoom( Packet * packet )
{
	StreamReader reader ( packet->getData() );
	int room_id			 = reader.get_int();
	reader.skip( sizeof(int)); //跳过sesstion_id
	int room_table_id	= reader.get_int();
	BYTE is_trace		= reader.get_byte();;
	DWORD trace_playerid = reader.get_uint();
	WORD pw_len	= reader.get_short();

	char strpw[128] = {0};
	char * password	 = reader.get_current_ptr();		//申请的密码
	if (pw_len >= 128)
		pw_len = 127;

	if (pw_len > 0)
		memcpy(strpw, password, pw_len);

	if (is_trace == 1 || is_trace == 2) {
		room_table_id = ActiveConnsList::instance()->GetRoomID(trace_playerid);
	}

	TableBase * table = PrivateTableManager::instance()->get_table( room_table_id );
	if ( table == NULL ){
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM, ERR_NOT_FOUND_ROOM );
		//printf("room not found table_id = %d\n",room_table_id);
		return false;
	}
	RoomConfigItem * room_conf = table->getRoomConf() ;
	if ( room_conf == NULL ){
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM , ERR_NOT_FOUND_ROOM );
		//printf("room not found room_id = %d\n",room_id);
		return false;
	}
	if ( m_player->get_user_gold() < room_conf->lower_limit_gold  )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM,ERR_NOT_ENOUGH_BALANCE );
		printf("user_id = %u user gold [ %lld ] < lower gold[%u] not allow player game \n", 
			m_player->get_user_id(),m_player->get_user_gold() , room_conf->lower_limit_gold  );
		return false;
	}
	if ( table->getPlayerCount() >= GAME_PLAYER  )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM, ERR_FULL_ROOM );
		return false ;
	}
	if ( table->getTableOwner() != m_player->get_user_id()  )
	{
		if ( is_trace != 2 && strcasecmp( table->getTablePwd() , strpw ) != 0  ){
			//printf("table = %d user_id = %d password not match, getTablePwd=%s, strpw=%s \n", table->getTableId()  ,m_player->get_user_id(), table->getTablePwd(), strpw );
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM, ERR_ROOM_PASSWORD );
			return false ;
		}
	}
	int nPriRoomPlayCount = Config::instance()->m_pri_room_playcount_limint;
	int nPriRoomVipLimit = Config::instance()->m_pri_room_vip_limit;
	if(((m_player->get_user_lost_count()+ m_player->get_user_win_count()) <nPriRoomPlayCount) || m_player->getUserInfo().viplevel  < nPriRoomVipLimit)
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM, ERR_PRIVATE_NEWER_LIMIT );
		return false;
	}
	return table->joinTable( m_player ) ;
}
void FrontClientHandler::handlePrivateRoomList( Packet * packet )
{
	StreamReader reader ( packet->getData() );
	//int is_request_all = reader.get_int();
	BYTE pageindex = reader.get_byte();
	DWORD userid = reader.get_int();

	StreamPacketBuilder::instance()->handlePrivateRoomList( this , userid, pageindex );
}

bool FrontClientHandler::checkEnterRoom(RoomConfigItem * room_config)
{
	if ( m_player->isNormalPlayer() )
	{
	#if 0	//printf( "zq room_config->high_limit_gold = %d\r\n", room_config->high_limit_gold );
		//判断下限
		if ( m_player->get_user_gold() < room_config->lower_limit_gold   ){
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM,ERR_NOT_ENOUGH_BALANCE );
			WL(LL_WARNING,"user_id = %u user gold [ %lld ] < lower gold[%u] not allow player game room_id = %d\n", 
				m_player->get_user_id(),m_player->get_user_gold() , room_config->lower_limit_gold , room_config->room_id);
			return false;
		}
		//判断上限
		if ( (room_config->high_limit_gold > 0) && (m_player->get_user_gold() > room_config->high_limit_gold) )
		{
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_ENTER_ROOM,ERR_NOT_ALLOWED_ENTER_LOWER_GOLD );
			WL(LL_WARNING,"user_id = %u user gold [ %lld ] < lower gold[%u] not allow player game room_id = %d\n", 
				m_player->get_user_id(),m_player->get_user_gold() , room_config->lower_limit_gold , room_config->room_id);
			return false;
		}
	#endif
	}
	else
	{
		//printf( "zq === m_player->get_user_gold() = %d room_config->high_limit_gold =%d \r\n", m_player->get_user_gold(), room_config->high_limit_gold );
		//机器人
		if ( m_player->get_user_gold() < room_config->lower_limit_gold   )
		{
			//机器人要给进去
			int gold = Config::instance()->m_global_config.system_give_gold - m_player->get_user_gold()  ;
			if ( room_config->room_id == 1 )
			{
				gold = Config::instance()->m_global_config.system_give_gold - m_player->get_user_gold()  ;
			}
			else if ( room_config->room_id == 3 )
			{
				gold			=	5000000 + rand() %  room_config->robot_give_gold ; //高级场多给机器人加金币
				gold			=   gold - m_player->get_user_gold() ;
			}
			else
			{
				gold			=	room_config->lower_limit_gold + rand() %  room_config->robot_give_gold ;
				gold			=   gold - m_player->get_user_gold() ;
			}
			SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_DDL,this );
			snprintf( req->sql , sizeof(req->sql),"call p_rechange_gold(%u,%lld,%d)",m_player->get_user_id(),m_player->get_user_score()->gold ,gold);
			m_player->add_user_gold( gold );
			DataBaseCommitThread::instance()->push( req ) ;
		}
		
		if ( (room_config->high_limit_gold > 0) && (m_player->get_user_gold() > room_config->high_limit_gold ) )
		{
			//机器人要给进去
			int gold			=	room_config->lower_limit_gold + rand() %  room_config->robot_give_gold ;
			int inc_gold		=  	gold - m_player->get_user_score()->gold ;

			SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_DDL,this );
			snprintf( req->sql , sizeof(req->sql),"call p_rechange_gold(%u,%lld,%d)",
				m_player->get_user_id(),m_player->get_user_score()->gold ,inc_gold);
			m_player->add_user_gold( inc_gold );
			DataBaseCommitThread::instance()->push( req ) ;
		}
	}
	return true ;
}
void FrontClientHandler::replaceHandle( FrontClientHandler * old )
{
	//先关了旧的句柄
	if ( !old->isClosed() )
	{
		//先删除新的玩家信息
		Player * player = old->getPlayer();
		if ( m_player != NULL )
		{
			GameMemoryPool::instance()->freePlayerClass( m_player ) ;
			m_player = NULL ;
		}
		//取原来的旧的玩家信息绑定到新的句柄
		m_player = player ; 
		//设置玩家为在线状态
		//玩家的句柄更新为新的
		m_player->set_handler( this ) ;

		//设置旧的玩家信息为NULL
		old->emptyPlayer() ;
		old->handle_close( old );//关闭

		//WL(LL_INFO,"replaceHandle emptyPlayer-> 11 \n" );
	}
	else
	{
		//updateUserInfo( old->getPlayer() );
		//先删除新的玩家信息
		if ( m_player != NULL )
		{
			GameMemoryPool::instance()->freePlayerClass( m_player ) ;
			m_player = NULL ;
		}
		//取原来的旧的玩家信息绑定到新的句柄
		m_player = old->getPlayer() ; 
		//设置玩家为在线状态
		//m_player->setPlayerStatus( PLAYER_STATUS_PLAYING );
		//玩家的句柄更新为新的
		m_player->set_handler( this ) ;

		//设置旧的玩家信息为NULL
		old->emptyPlayer() ;
		
		//WL(LL_INFO,"replaceHandle emptyPlayer-> 22  \n" );
	}


}
bool FrontClientHandler::restoreScene( int uid )
{
	FrontClientHandler * old = CloseConnsList::instance()->find( uid ) ;
	if ( old  )
	{
		Player * player = old->getPlayer() ;
		if ( player ) //
		{
			if ( player->getTable() ) //在游戏桌上
			{
				WL(LL_INFO,"player %u table = %d restore sence close chair = %d \n",player->get_user_id() , player->getTable()->getTableId() , player->get_chair_id()  );
				replaceHandle( old );
				//恢复现场
				if( player->getTable()->getRoomConf() && player->getTable()->getRoomConf()->room_type == ROOM_TYPE_NIUNIU)
				{
					printf("FrontClientHandler::restoreScene  nUserID:%d  in nn_room \n", player->get_user_id());
					StreamPacketBuilder::instance()->notifyNNEnterRoomRsp( m_player );	
				}
				else
				{
					StreamPacketBuilder::instance()->respEnterRoom( m_player );	
				}
				CloseConnsList::instance()->release( old ) ;
				return true ;
			}
		}
		CloseConnsList::instance()->release( old ) ;
	}
	return false;
}

void FrontClientHandler::handleProcLucky( Packet* packet )
{

}

bool FrontClientHandler::enableRelease()
{
	if ( m_player && m_player->getTable() ) //只要在桌子上
	{
		return false ;
	}
	return true ;
}

void FrontClientHandler::handleUserDetail( Packet * packet )
{
	//struct timeval t_start, t_end;
    //long cost_time = 0;
	//gettimeofday(&t_start, NULL);

	//WL(LL_DEV, "Start time: %ld us \n", t_start.tv_usec);
	StreamReader reader ( packet->getData() );
	DWORD userId			 = reader.get_uint(); 

	FrontClientHandler * pHandle = ActiveConnsList::instance()->find( userId ) ;
	if (pHandle) {
		Player *  pPlayer = pHandle->getPlayer();
		if ( pPlayer )
		{
			StreamPacketBuilder::instance()->respUserDetail(pPlayer, this);
			return;
		}
	}

	{
		SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		snprintf( req->sql, sizeof(req->sql), "call sp_get_user_detail(%u)", userId );
		req->client		= this;
		req->req_type	= REQ_TYPE_GET_USER_DETAIL;
		//printf( "zq handleUserDetail req->sql=%s\r\n", req->sql );
		DataBasePacketDataThread::instance()->push( req );
	}

	//get end time
	//gettimeofday(&t_end, NULL);
	//printf("End time: %ld us", t_end.tv_usec);

	//calculate time slot
	//cost_time = t_end.tv_usec - t_start.tv_usec;

	//WL(LL_DEV, "handleUserDetail End time: %ld us, Cost time: %ld us, test_num = %d \n", t_end.tv_usec, cost_time, test_num);
}

void FrontClientHandler::handleGetUserDetailResult(SQLResp * resp)
{
	if (m_player == NULL)
		return;
	sendPacket( MSG_RESP_USER_DETAIL , resp->data , resp->len );
}

void FrontClientHandler::handleFriendAddByGiftResult(SQLResp * resp)
{
	if (m_player == NULL)
	{
		return;
	}

	StreamReader reader ( resp->data );
	BYTE result = reader.get_byte(); 
	DWORD src_userId = reader.get_uint(); 
	DWORD des_userId = reader.get_uint(); 
	DWORD giftid = reader.get_int(); 
	BYTE sex = reader.get_byte(); 
	INT64 gold = reader.get_int64(); 
	

	//printf( "zq handleFriendAddByGiftResult result = %d  \r\n", result );
	if ( result == 0 )
	{
		result = RESULT_OK;
	}
	else
	{
		//result = RESULT_FAILD;
		char msgdata[1024] = {0};
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_int64(m_player->get_user_enable_gold());
		sendPacket( MSG_RESP_ADD_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );
		return;
	}

	FriendInfoEx * pFriend = m_player->GetFriendInfo(des_userId);
	UserInfo friendinfo;
	if (!pFriend)
	{
		friendinfo.user_id = des_userId;
		friendinfo.user_sex = sex;
		friendinfo.user_score.gold = gold;
		WORD pick_name_len = reader.get_ushort();
		if (pick_name_len >= PICTURE_HEAD_LENGTH)
			pick_name_len = PICTURE_HEAD_LENGTH-1;
		memcpy(friendinfo.head_picture, reader.get_current_ptr(), pick_name_len);
		reader.skip(pick_name_len);

		WORD nick_name_len = reader.get_ushort();
		if (nick_name_len >= NAME_LENGTH)
			nick_name_len = NAME_LENGTH-1;
		memcpy(friendinfo.nick_name, reader.get_current_ptr(), nick_name_len);
		reader.skip(nick_name_len);

		WORD sign_len = reader.get_ushort();
		if (sign_len >= SIGN_MAX_LEN)
			sign_len = SIGN_MAX_LEN-1;
		memcpy(friendinfo.char_sign, reader.get_current_ptr(), sign_len);
		reader.skip(sign_len);
		pFriend = m_player->AddFriendEx( des_userId, time(NULL), friendinfo );
	}
	if ( pFriend )
	{
		//printf( "zq handleFriendAddByGiftResult pFriend != NULL\r\n" );
		FriendInfo friendmsg;
		m_player->SendOneFriendToClient(&friendinfo);
		char mail_data[128] = {0};
		snprintf( mail_data , sizeof(mail_data),"您成功添加%s为好友", pFriend->nick_name );
		AddMail(m_player->get_user_id(), EMAIL_TYPE_ADD_FRIEND, mail_data);

		memset( mail_data,0 , sizeof(mail_data) );
		snprintf( mail_data , sizeof(mail_data),"%s添加您为好友", m_player->get_nick_name() );
		AddMail(des_userId, EMAIL_TYPE_ADD_FRIEND, mail_data);
	}
	m_player->set_user_gold( reader.get_int64());
	int giftnum = reader.get_int();
	int charmnum = reader.get_int();
	//printf( "zq handleFriendAddByGiftResult send msg to user gold %lld \r\n", m_player->get_user_gold() );
	{
		char msgdata[1024] = {0};
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_int64(m_player->get_user_gold());
		sendPacket( MSG_RESP_ADD_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );
	}

	//如果对方在线
	FrontClientHandler * pOtherHandle = ActiveConnsList::instance()->find(des_userId);
	if ( pOtherHandle && pOtherHandle->getPlayer() )
	{
		FriendInfoEx * pFriend2 = pOtherHandle->getPlayer()->AddFriendEx(m_player->get_user_id(), time(NULL), m_player->getUserInfo());
		if ( pFriend2 )
		{
			pOtherHandle->getPlayer()->SendOneFriendToClient(&(m_player->getUserInfo()));
			pOtherHandle->getPlayer()->ChangeGiftCount(giftid, giftnum, true);
			{
				//发送好友添加消息
				char msgdata[512] = {0};
				StreamWriter stream_out(msgdata, sizeof(msgdata));
				stream_out.add_uint( m_player->get_user_id() );
				stream_out.add_uint( giftid );	
				WORD nick_name_len = strlen(m_player->getUserInfo().nick_name);
				stream_out.add_word(nick_name_len);
				stream_out.appand(m_player->getUserInfo().nick_name, nick_name_len);
				stream_out.add_byte( giftnum );//增加的礼物数量
				stream_out.add_int( charmnum );	//魅力值
				pOtherHandle->getPlayer()->getUserInfo().charm = charmnum;
				pOtherHandle->sendPacket( MSG_NOTIFY_ADD_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );
				StreamPacketBuilder::instance()->notifyGiftChange( MSG_NOTIFY_FRIEND_GIVE_GIFT, m_player->getTable(), m_player );
			}
		}
	}
	
}

void FrontClientHandler::handleRestoreScene( Packet * packet )
{
	StreamReader reader ( packet->getData() );
	int userId			 = reader.get_int(); //要恢复的用户Id

	handleRestoreSceneByUserid(userId);
}

bool FrontClientHandler::handleRestoreSceneByUserid( int userId )
{
	FrontClientHandler * old = CloseConnsList::instance()->find( userId ) ;
	if ( old  )
	{
		Player * player = old->getPlayer() ;
		if ( player ) //
		{
			if ( player->getTable() ) //在游戏桌上
			{
				WL(LL_INFO,"player %u table = %d restore sence close chair = %d \n",
					player->get_user_id() , player->getTable()->getTableId() , player->get_chair_id()  );
				replaceHandle( old );
				//恢复现场
				StreamPacketBuilder::instance()->respEnterRoom( m_player );
				CloseConnsList::instance()->release( old ) ; 
				return true;
			}
		}
		CloseConnsList::instance()->release( old ) ;
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_RESTORE_SCENE ,ERR_USER_NOT_FOUND );
	}
	else
	{
		StreamPacketBuilder::instance()->respError( this , MSG_RESP_RESTORE_SCENE ,ERR_USER_NOT_FOUND );
	}

	return false;
}

// 领取救济金
void FrontClientHandler::handleGetHelpGold(Packet * packet)
{
	if (!m_player)
		return;
#if 0
	RoomDirector * roomDirector = RoomManager::instance()->findRoom( 1 ) ;
	if ( roomDirector == NULL )
		return ;
	
	RoomConfigItem * room_conf = roomDirector->getRoom() ;
	if ( room_conf == NULL )
		return;
#endif
	int bankruptcynum = 3;
	int bankruptcygold = 3000;
	map< int , GameDataConfig >::iterator iter = Config::instance()->m_gamedataconfig.find( DATA_CONFIG_BANKUPTCY );
	if ( iter != Config::instance()->m_gamedataconfig.end() )
	{
		bankruptcynum = iter->second.valuelist[0];
		bankruptcygold = iter->second.valuelist[1];
	}
	UserInfo & refinfo = m_player->getUserInfo();
	if (refinfo.user_score.gold > 600 )
	{
		StreamPacketBuilder::instance()->handleGetHelpGold( m_player, false, refinfo.today_get_help_count, bankruptcynum , 1);
		return;
	}

	if (refinfo.today_get_help_count >= bankruptcynum)
	{
		StreamPacketBuilder::instance()->handleGetHelpGold( m_player, false, refinfo.today_get_help_count, bankruptcynum , 2);
		return;
	}
	m_player->set_user_gold(refinfo.user_score.gold+bankruptcygold);
	refinfo.today_get_help_count++;
	//printf( "zq refinfo.user_score.gold  = %lld  usergold: %lld\r\n", refinfo.user_score.gold, m_player->get_user_gold() ); 
	StreamPacketBuilder::instance()->handleGetHelpGold(m_player, true, refinfo.today_get_help_count, bankruptcynum );
	StreamPacketBuilder::instance()->notifyUpdatePlayerGold(m_player->getTable(), m_player);

	//更新数据库数据
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_UPDATE_WEALTH , NULL );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call SP_UpdateUserWealth(%u,%d,%d, %d)", m_player->get_user_id() , bankruptcygold, 0, 4 );
	//printf( "zq handleGetHelpGold req->sql=%s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );

}

// 领取签到奖励
void FrontClientHandler::handleGetSignInReward(Packet * packet)
{
	if (!m_player)
		return;

	StreamReader reader ( packet->getData() );
	int userId			 = reader.get_int(); //要恢复的用户Id
}

// 领取登陆宝箱
void FrontClientHandler::handleGetLoginRewardBox(Packet * packet)
{
}

// 玩家短线重连
void FrontClientHandler::handleReConnectServer(Packet * packet)
{
	StreamReader reader ( packet->getData() );
	int userId			 = reader.get_int();

	BYTE need_login = RESULT_OK;
	if (m_player != NULL) {
		need_login = RESULT_OK;
	}
	else {
		if (handleRestoreSceneByUserid(userId))
			need_login = RESULT_OK;
		else
			need_login = RESULT_FAILD;
	}

	u8_t m_data [ 1042 ];
	StreamWriter stream_out(m_data,sizeof(m_data));
	stream_out.add_byte( need_login );
	sendPacket( MSG_RESP_RECONNECT_SERVER, stream_out.get_buffer() , stream_out.get_buffer_len() );
}

// 钻石兑换金币
void FrontClientHandler::handleGemSwapGolds(Packet * packet)
{

}

// 更新人物头像
void FrontClientHandler::handleUpdateHeadPicture(Packet * packet)
{
	if (!m_player)
		return;

	if (packet->getDataLen() > PICTURE_HEAD_LENGTH) {
		WL(LL_DEV ,"handleUpdateHeadPicture  str=%s\n", packet->getData());
		return;
	}

	char sztmpBuf[64] = {0};
	memcpy(sztmpBuf, packet->getData(), packet->getDataLen());
	
	m_player->getUserInfo().set_head_picture(sztmpBuf);

	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_update_head_picture(%u,'%s')", m_player->get_user_id() , sztmpBuf );
	WL(LL_DEV ,"req handleUpdateHeadPicture  sql=%s\n", req->sql);
	req->req_type	= REQ_TYPE_UPDATE_HEAD_PICTURE ;
	DataBasePacketDataThread::instance()->push( req );

	u8_t senddata [ 64 ] = {0};
	StreamWriter stream_out(senddata,sizeof(senddata));
	stream_out.add_byte( 1 );
	sendPacket( MSG_RESP_CHANGE_HEAD_PICTURE, stream_out.get_buffer() , stream_out.get_buffer_len() );

	m_player->OnChangeHeadPicture();
}

// 好友系统
void FrontClientHandler::handleReqAddFriend(Packet * packet)
{
	if (!m_player)
		return;	

	StreamReader reader ( packet->getData() );
	BYTE add_type = reader.get_byte();
	DWORD playerid = reader.get_uint();
	DWORD giftid = reader.get_uint();
	DWORD giftnum = reader.get_byte();

	char msgdata[1024];
	BYTE result = RESULT_OK;
	do {

		if ( giftnum < 0 ||  m_player->get_user_id() == playerid) {
			result = RESULT_FAILD;
			break;
		}

		if (!m_player->IsCanAddFirend()) {
			result = ERR_MAX_FRIENDS_COUNT;
			break;
		}

		if (m_player->GetFriendInfo(playerid) != NULL) {
			result = RESULT_FAILD;
			break;
		}

		FrontClientHandler * pOtherHandle = ActiveConnsList::instance()->find(playerid);
		if (add_type == 1)
		{
			if (pOtherHandle == NULL) {
				result = ERR_FRIEND_OFF_LINE;
				break;
			}
			Player * pOtherPlayer = pOtherHandle->getPlayer();
			if (pOtherPlayer == NULL) {
				result = ERR_FRIEND_OFF_LINE;
				break;
			}
			if (!pOtherPlayer->IsCanAddFirend()) {
				result = ERR_OTHER_MAX_FRIENDS_COUNT;
				break;		
			}

			StreamWriter stream_out(msgdata, sizeof(msgdata));
			stream_out.add_uint( m_player->get_user_id() );
			stream_out.add_uint( 0 );	
			WORD nick_name_len = strlen(m_player->getUserInfo().nick_name);
			stream_out.add_word(nick_name_len);
			stream_out.appand(m_player->getUserInfo().nick_name, nick_name_len);
			stream_out.add_byte( 0 );//礼物数量
			stream_out.add_int( 0 );//魅力值  礼物
			pOtherHandle->sendPacket( MSG_NOTIFY_ADD_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );
			//printf( "MSG_NOTIFY_ADD_FRIEND =   userid = %d \r\n", pOtherHandle->getPlayer()->get_user_id() );
		}
		else
		{
			Gift_Confit * pGift = Config::instance()->GetGiftConfig(giftid);
			if (pGift == NULL) {
				result = RESULT_FAILD;
				break;
			}

			if (pGift->give_golds > m_player->get_user_gold()) {
				result = ERR_NOT_ENOUGH_GOLDS;
				break;
			}
			
			if (pOtherHandle != NULL)
			{
				Player * pOtherPlayer = pOtherHandle->getPlayer();
				if (pOtherPlayer == NULL) {
					result = RESULT_FAILD;
					break;
				}
			
				if (!pOtherPlayer->IsCanAddFirend()) {
					result = ERR_OTHER_MAX_FRIENDS_COUNT;
					break;
				}
			}
			//请求数据库
			handleGiftAddFriend( m_player->get_user_id(), playerid, giftid, pGift->give_golds, giftnum );
			return;
		}
	} while (0);

	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_int64(m_player->get_user_gold()- m_player->getTableCoin());
		sendPacket( MSG_RESP_ADD_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );
	}
}

void FrontClientHandler::handleReqDeleteFriend(Packet * packet)
{
	if (!m_player)
		return;	

	StreamReader reader ( packet->getData() );
	DWORD friendid = reader.get_uint();

	char msgdata[1024] = {0};
	BYTE result = RESULT_OK;
	do {
		if (!m_player->DeleteFriend(friendid)) {
			result = ERR_NO_THIS_FRIEND;
			break;
		}

		handleDeleteFriend(m_player->get_user_id(), friendid);

		FrontClientHandler * pOtherHandle = ActiveConnsList::instance()->find(friendid);
		if (pOtherHandle != NULL) {
			Player * pOtherPlayer = pOtherHandle->getPlayer();
			if (pOtherPlayer != NULL) {
				if (pOtherPlayer->DeleteFriend(m_player->get_user_id()))
				{
					StreamWriter stream_out(msgdata, sizeof(msgdata));
					stream_out.add_uint( m_player->get_user_id() );
					//printf( "MSG_NOTIFY_DELETE_FRIEND========= stream_out.get_buffer_len() = %d friendid = %d\r\n", stream_out.get_buffer_len(),friendid );
					pOtherHandle->sendPacket( MSG_NOTIFY_DELETE_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );	
				}
			}
		}
	} while (0);

	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		sendPacket( MSG_RESP_DELETE_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );
	}
}

void FrontClientHandler::handleReqSendMsgToFriend(Packet * packet)
{
	if (!m_player)
		return;	

#define MAX_FRIEND_CHAT_MSG_LEN		1024

	StreamReader reader ( packet->getData() );
	DWORD friendid = reader.get_uint();
	WORD  msg_len = reader.get_ushort();
	char * chatmsg = reader.get_current_ptr();

	if (packet->getDataLen() < msg_len + 2 + 4)
		return;

	FrontClientHandler * pOtherHandle = ActiveConnsList::instance()->find(friendid);
	if (pOtherHandle != NULL) {
		Player * pOtherPlayer = pOtherHandle->getPlayer();
		if (pOtherPlayer != NULL) {
			char msgdata[2048];
			StreamWriter stream_out(msgdata, sizeof(msgdata));
			stream_out.add_uint( m_player->get_user_id() );
			stream_out.add_word( msg_len );
			stream_out.appand(chatmsg, msg_len);
			sendPacket( MSG_NOTIFY_SEND_MSG_TO_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );	
		}
	}
	else {
		char msgdata[MAX_FRIEND_CHAT_MSG_LEN] = {0};
		if (msg_len < MAX_FRIEND_CHAT_MSG_LEN && msg_len > 0) {
			memcpy(msgdata, chatmsg, msg_len);
			handleAddFriendMsg(m_player->get_user_id(), friendid, time(NULL), msg_len, chatmsg);
		}
	}
}

void FrontClientHandler::handleReqAnswerAddFriend(Packet * packet)
{
	if (!m_player)
		return;	

	StreamReader reader ( packet->getData() );
	BYTE  answer = reader.get_byte();
	DWORD friendid = reader.get_uint();
	
	FrontClientHandler * pOtherHandle = ActiveConnsList::instance()->find(friendid);
	if (pOtherHandle == NULL) 
		return;

	Player * pOtherPlayer = pOtherHandle->getPlayer();
	if (pOtherPlayer == NULL) 
		return;
	
	if (answer == 1)
	{
		time_t curtime = time(NULL);
		FriendInfoEx * pFriend1 = m_player->AddFriendEx(friendid, curtime, pOtherPlayer->getUserInfo());
		FriendInfoEx * pFriend2 = pOtherPlayer->AddFriendEx(m_player->get_user_id(), curtime, m_player->getUserInfo());

		m_player->SendOneFriendToClient( &(pOtherPlayer->getUserInfo()) );
		pOtherPlayer->SendOneFriendToClient( &(m_player->getUserInfo()) );
		
		// 写入数据库
		handleAddFriend(m_player->get_user_id(), friendid, curtime);
		handleAddFriend(friendid, m_player->get_user_id(), curtime);

		if (pFriend1) {
			char mail_data[512] = {0};
			snprintf( mail_data , sizeof(mail_data),"您成功添加%s为好友", pFriend1->nick_name );
			AddMail(m_player->get_user_id(), EMAIL_TYPE_ADD_FRIEND, mail_data);
		}

		if (pFriend2) {
			char mail_data[512] = {0};
			char desbuffer1[32] = {0};
			char desbuffer2[32] = {0};
			snprintf( mail_data , sizeof(mail_data),"您成功添加%s为好友", pFriend2->nick_name );
			AddMail(friendid, EMAIL_TYPE_ADD_FRIEND, mail_data);
		}
	}

	{
		char msgdata[1024];
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( answer );
		stream_out.add_uint( m_player->get_user_id() );
		WORD nick_name_len = strlen(m_player->getUserInfo().nick_name);
		stream_out.add_word(nick_name_len);
		stream_out.appand(m_player->getUserInfo().nick_name, nick_name_len);
		pOtherHandle->sendPacket(MSG_NOTIFY_ANSWER_ADD_FRIEND, stream_out.get_buffer(), stream_out.get_buffer_len() );	
	}
}

void FrontClientHandler::LoadFriendData(void)
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	//snprintf( req->sql , sizeof(req->sql) ,"call sp_friend_get_list(%u)",m_player->get_user_id() );
	*(int*)req->sql = m_player->get_user_id();
	req->client		= this;
	req->req_type	= REQ_TYPE_FRIEND_GET_LIST;
	//printf( "zq handleReqGetFriendList ===========\r\n" );
	DataBasePacketDataThread::instance()->push( req );
}

void FrontClientHandler::changeUserOnlineStatus(BYTE status, DWORD nUserID)
{
	SQLReq *req = SQLMemoryPool::instance()->mallocReq();
	snprintf(req->sql, sizeof(req->sql), "call sp_user_online(%d, %d, %lld)", nUserID, status,time(NULL));

	DataBaseCommitThread::instance()->push( req );;
	
}

void FrontClientHandler::checkUserMoneyLegal()
{
	if(! m_player)
		return;

	SQLReq *req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql, sizeof(req->sql), "SELECT gold FROM user_info WHERE user_id = %u limit 1", m_player->get_user_id());
	req->req_type = REQ_TYPE_ENTER_ROOM;
	req->id = m_player->get_user_id();
	req->client = this;
	DataBaseReadThreadPool::instance()->pushQueue(req);
}

bool  FrontClientHandler::userOperateAllowWhenAllin(FrontClientHandler *pOwne, FrontClientHandler *pOther)
{
	if(pOwne == NULL || pOther == NULL)
		return false;
	Player *pUserOwn = pOwne->getPlayer();
	Player *pUserOther = pOther->getPlayer();
	if(pUserOther == NULL || pUserOther == NULL)
		return false;

	if( (pUserOwn->getTable() && pUserOwn->isAllIn() ) ||( pUserOther->getTable() && pUserOther->isAllIn() == true))
	{
		return false;
	}

	return true;
}

void FrontClientHandler::handleReqGetFriendList(Packet * packet)
{
	//printf("handleReqGetFriendList  \n");
	if (!m_player)
		return;	

	if (m_player->IsLoadFriend())
	{
		m_player->SendFriendToClient();
		return;
	}

	LoadFriendData();
}

//新数据格式请求
void FrontClientHandler::handleReqGetFriendListEx(Packet * packet)
{
	if (!m_player)
		return;	

	if (m_player->IsLoadFriend())
	{
		m_player->SendFriendToClientEx();
		return;
	}

	LoadFriendData();
}

void FrontClientHandler::handleGetFriendListResult(SQLResp * resp)
{
	if (!m_player)
		return ;
	m_player->InitFriendFromDB(resp->data, resp->len);
}

void FrontClientHandler::handleReqEnemyList(Packet * packet)
{
	if (!m_player)
		return ;

	m_player->SendEnemyToClient();
}

void FrontClientHandler::handleGetEnemyListResult(SQLResp * resp)
{
	if (!m_player)
		return ;

	m_player->InitEnemyFromDB(resp->data, resp->len);
}

void FrontClientHandler::handleReqInviteFriendGame(Packet * packet)
{
	if (!m_player)
		return;	

	StreamReader reader ( packet->getData() );
	DWORD friendid = reader.get_uint();

	int result = RESULT_OK;
	do {
		FrontClientHandler * pOtherHandle = ActiveConnsList::instance()->find(friendid);		
		if (pOtherHandle == NULL) {
			result = ERR_FRIEND_OFF_LINE;
			break;
		}
		Player *pOtherPlayer = pOtherHandle->getPlayer();
		if(pOtherPlayer == NULL)
		{
			result = ERR_FRIEND_OFF_LINE;
			break;
		}
		TableBase * pTmp = pOtherPlayer->getTable();
		if(pTmp && pTmp->getRoomConf()->room_type == ROOM_TYPE_NIUNIU)
		{
			result = NN_ERROR_NOT_ALLOW_INVITE;
			break;
		}
		
		{
			char msgdata[1024];
			StreamWriter stream_out(msgdata, sizeof(msgdata));
			stream_out.add_int( m_player->get_table_id() );
			int nick_len = strlen(m_player->get_nick_name());
			stream_out.add_short( nick_len );
			stream_out.appand(m_player->get_nick_name(), nick_len);

			TableBase * pTable = m_player->getTable();
			if (pTable) {
				RoomConfigItem * pConfig = pTable->getRoomConf();
				stream_out.add_int(pConfig->room_id);
				stream_out.add_int(pConfig->lower_limit_gold);
				stream_out.add_int(pConfig->high_limit_gold);
			}
			else {
				stream_out.add_int(0);
				stream_out.add_int(0);
				stream_out.add_int(0);
			}
			stream_out.add_int(m_player->get_user_id());

			pOtherHandle->sendPacket(MSG_NOTIFY_INVITE_FRIEND_GAME, stream_out.get_buffer(), stream_out.get_buffer_len() );	
		}
		
	} while (0);

	{
		char msgdata[1024];
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		sendPacket(MSG_RESP_INVITE_FRIEND_GAME, stream_out.get_buffer(), stream_out.get_buffer_len() );	
	}	
}


void FrontClientHandler::handleReqGivePlayerGift(Packet * packet)
{
	if (!m_player)
		return;	

	StreamReader reader ( packet->getData() );
	int  giftid = reader.get_int();
	DWORD give_userid = reader.get_uint();

	bool isOk = true;
	FrontClientHandler *pOther = ActiveConnsList::instance()->find(give_userid);

	//??ǰ????????? ??????????
	if(pOther && pOther->getPlayer() && pOther->getPlayer()->getTable()) 
	{
		isOk = userOperateAllowWhenAllin(m_player->get_handler(),  pOther);
		if( !isOk)
		{
			return;
		}
	}

	
	char msgdata[1024];
	BYTE result = RESULT_OK;
	do {
		Gift_Confit * pGift = Config::instance()->GetGiftConfig(giftid);
		if (pGift == NULL) {
			result = RESULT_FAILD;
			break;
		}

		if ( giftid ==  3 ||  giftid == 4  || giftid == 5 )
		{
			if ( m_player->get_phone_number() == NULL)
			{
				result = ERR_GIFT_CAN_NOT_GIVE;
				break;
			}
		}
		
		DWORD roommingold = 0;
		if ( Config::instance()->get_room( m_player->GetCurRoomID()) )
		{
			if ( m_player->GetCurRoomID() == ROOM_CONFI_ID_1 )
			{
				roommingold = Config::instance()->get_room( m_player->GetCurRoomID())->room.lower_limit_gold;
			}
			else
			{
				roommingold = Config::instance()->get_room( m_player->GetCurRoomID())->room.cell_gold*3;
			}
			
		}
		//printf( "zq roommingold=%d usergold=%d giftgold=%d\r\n", roommingold, m_player->get_user_gold(), pGift->give_golds );
		if ( (pGift->give_golds + roommingold) > m_player->get_user_enable_gold() )
		{
			result = ERR_NOT_ENOUGH_GOLDS;
			break;
		}

		handleGiveGift( m_player->get_user_id(), giftid, give_userid, pGift->give_golds );
		return;
	} while (0);

	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_int64( m_player->get_user_gold() );
		sendPacket( MSG_RESP_GIVE_PLAYER_GIFT, stream_out.get_buffer(), stream_out.get_buffer_len() );
	}
}

void FrontClientHandler::handleReqClearEggs(Packet * packet)
{
	if (!m_player)
		return;

	StreamReader reader ( packet->getData() );
	int  clear_count = reader.get_int();

	char msgdata[1024];
	BYTE result = RESULT_OK;
	DWORD need_golds = 0;
	do {
		if (m_player->getUserInfo().aggs < clear_count) {
			result = RESULT_FAILD;
			break;
		}

		need_golds = 10000*clear_count;
		if (need_golds > m_player->get_user_gold()) {
			result = ERR_NOT_ENOUGH_GOLDS;
			break;
		}

		//m_player->set_user_gold(m_player->get_user_gold() - need_golds);
		//m_player->getUserInfo().aggs -= clear_count;
		//更新数据库数据
		SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_SELL_GIFT, this );
		req->id = m_player->get_user_id();
		snprintf( req->sql , sizeof(req->sql) ,"call SP_Sell_Gift(%u,%d,%d, %d, %d)", m_player->get_user_id() , 2, 0, -need_golds, clear_count );
		//printf( "zq  ======req->sql=%s\r\n",req->sql ); 
		DataBaseReadThreadPool::instance()->pushQueue( req );
		return;
	} while (0);

	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_int64(m_player->get_user_gold());
		stream_out.add_int( m_player->getUserInfo().aggs );
		stream_out.add_int( 0 );	//消耗的金币值
		stream_out.add_int( 0 );	//魅力值
		sendPacket( MSG_RESP_CLEAR_EGGS, stream_out.get_buffer(), stream_out.get_buffer_len() );
	}
}

void FrontClientHandler::handleReqSellGift(Packet * packet)
{
	if (!m_player)
		return;


	StreamReader reader ( packet->getData() );
	int kind_count = reader.get_byte();//礼物id
	WORD giftid	= reader.get_ushort();
	WORD giftcount = reader.get_ushort();
	//printf( "zq giftid = %d giftcount = %d\r\n", giftid, giftcount );
	if (kind_count > 5)
		kind_count = 5;

	DWORD add_golds = 0;
	char msgdata[1024] = {0};
	BYTE result = RESULT_OK;
	do {
		Gift_Confit * pGift = Config::instance()->GetGiftConfig( giftid );
		if (pGift == NULL) {
			result = RESULT_FAILD;
			break;
		}

		/*if (m_player->GetGiftCount(giftid) < giftcount) {
			result = ERR_NO_GIFT;
			break;
		}*/

		add_golds = giftcount*pGift->sell_golds;
		
		//m_player->ChangeGiftCount( giftid, giftcount, false );
		//m_player->set_user_gold(m_player->get_user_gold() + add_golds);
		
		//更新用户金币
		//StreamPacketBuilder::instance()->notifyUpdatePlayerGold(m_player->getTable(), m_player);

		//更新数据库数据
		SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_SELL_GIFT, this );
		req->id = m_player->get_user_id();
		snprintf( req->sql , sizeof(req->sql) ,"call SP_Sell_Gift(%u,%d,%d, %d, %d)", m_player->get_user_id() , pGift->gift_id, pGift->give_golds*giftcount, pGift->sell_golds*giftcount, giftcount );

		//printf( "zq  ======req->sql=%s\r\n",req->sql ); 
		DataBaseReadThreadPool::instance()->pushQueue( req );
		return;
	} while (0);
	//printf( "zq add_golds = %d, result = %d\r\n", add_golds, result );
	StreamWriter stream_out(msgdata, sizeof(msgdata));
	stream_out.add_byte( result );
	stream_out.add_int64(m_player->get_user_gold());
	stream_out.add_uint( m_player->getUserInfo().flower );
	stream_out.add_uint( m_player->getUserInfo().aggs );
	stream_out.add_uint( m_player->getUserInfo().car );
	stream_out.add_uint( m_player->getUserInfo().villa );
	stream_out.add_uint( m_player->getUserInfo().yacht );
	stream_out.add_uint( 0 );//失败  增加金币为0
	stream_out.add_uint( 0 );//失败  魅力为0
	sendPacket( MSG_RESP_SELL_GIFT, stream_out.get_buffer(), stream_out.get_buffer_len() );
}

void FrontClientHandler::OnDBSellGift( SQLResp *resp )
{
	int result = 1;
	if ( !m_player )
	{
		return;
	}
	if ( resp->result == 0 )
	{
		result = ERR_SYSTEM;
	}

	DB_SELL_GIFT_RET *pMsg = (DB_SELL_GIFT_RET*)resp->data;

	if ( pMsg->result != 0 )
	{
		result = ERR_NO_GIFT ;
	}
	if (pMsg->result == 0)

	{
		m_player->SetGiftCount(pMsg->giftid, pMsg->giftnum);
		//m_player->ChangeGiftCount( pMsg->giftid, pMsg->giftcount, false );
		m_player->set_user_gold( m_player->get_user_gold() + pMsg->sellgold);
		//更新用户金币
		StreamPacketBuilder::instance()->notifyUpdatePlayerGold(m_player->getTable(), m_player);
	}
	if ( pMsg->giftid == 2 )
	{
		char msgdata[1024] = {0};
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_int64(m_player->get_user_gold());
		stream_out.add_int( m_player->getUserInfo().aggs );//
		stream_out.add_int( pMsg->sellgold );
		stream_out.add_int( pMsg->charmnum );
		sendPacket( MSG_RESP_CLEAR_EGGS, stream_out.get_buffer(), stream_out.get_buffer_len() );
	}
	else
	{
		char msgdata[1024] = {0};
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_int64(m_player->get_user_gold()-m_player->getTableCoin());
		stream_out.add_uint( m_player->getUserInfo().flower );
		stream_out.add_uint( m_player->getUserInfo().aggs );
		stream_out.add_uint( m_player->getUserInfo().car );
		stream_out.add_uint( m_player->getUserInfo().villa );
		stream_out.add_uint( m_player->getUserInfo().yacht );
		stream_out.add_uint( pMsg->sellgold );
		stream_out.add_int( pMsg->charmnum );
		m_player->getUserInfo().charm = pMsg->charmnum;	//用户魅力值变动

		
		sendPacket( MSG_RESP_SELL_GIFT, stream_out.get_buffer(), stream_out.get_buffer_len() );
		StreamPacketBuilder::instance()->notifyGiftChange( MSG_NOTIFY_SELL_GIFT, m_player->getTable(), m_player );
	}
	
}

void FrontClientHandler::OnDBGiveGift( SQLResp *resp )
{
	//printf( "OnDBGiveGift==========\r\n" );
	int result = 1;
	DB_GIVE_GIFT_RET *pRetMsg = (DB_GIVE_GIFT_RET*)resp->data;
	if ( !m_player )
	{
		return;
	}
	if ( (resp->result == 0) || (pRetMsg->result==1) )
	{
		printf( "resp->result = %d || pRetMsg->result= %d\r\n", resp->result, pRetMsg->result );
		result = RESULT_FAILD;
	}
	else
	{
		
		int giftid = pRetMsg->giftid;
		DWORD give_userid = pRetMsg->giveuid;
		m_player->set_user_gold( m_player->get_user_gold() - pRetMsg->changegold);
		//printf( "user gold : %lld, changegold : %d give_userid : %d\r\n", m_player->get_user_gold(), pRetMsg->changegold, give_userid );
		FrontClientHandler * pOtherHandle = ActiveConnsList::instance()->find( give_userid );
		if (pOtherHandle != NULL)
		{
			Player * pOtherPlayer = pOtherHandle->getPlayer();
			if (pOtherPlayer != NULL) {
				pOtherPlayer->ChangeGiftCount(giftid, 1, true);
				char msgdata[1024] = {0};
				StreamWriter stream_out(msgdata, sizeof(msgdata));
				stream_out.add_uint( m_player->get_user_id() );
				stream_out.add_uint( give_userid );
				stream_out.add_uint( giftid );
				stream_out.add_uint( pOtherPlayer->GetGiftCount(giftid) );
				int nickname = strlen(m_player->get_nick_name());
				stream_out.add_short((short)nickname);
				stream_out.appand(m_player->get_nick_name(), nickname);
				stream_out.add_int64(m_player->get_user_gold() - m_player->getTableCoin());
				stream_out.add_int( pRetMsg->charmnum );
				pOtherPlayer->getUserInfo().charm = pRetMsg->charmnum;//改变用户魅力值
				pOtherHandle->sendPacket( MSG_NOTIFY_SEND_GIVE_GIFT, stream_out.get_buffer(), stream_out.get_buffer_len() );
				//printf( "table send msg \r\n" );
				if (pOtherPlayer->getTable()) {
					StreamPacketBuilder::instance()->broadcast(pOtherPlayer->getTable(), MSG_NOTIFY_SEND_GIVE_GIFT, (BYTE*)stream_out.get_buffer(), 
						stream_out.get_buffer_len(), pOtherPlayer->get_chair_id());
				}
			}
		}
	}
	char msgdata[1024] = {0};
	StreamWriter stream_out( msgdata, sizeof(msgdata) );
	stream_out.add_byte( result );
	stream_out.add_int64( m_player->get_user_gold() - m_player->getTableCoin()); //??ȥ????Ľ?
	sendPacket( MSG_RESP_GIVE_PLAYER_GIFT, stream_out.get_buffer(), stream_out.get_buffer_len() );
}


// 老虎机
void FrontClientHandler::handleReqLotteryBegin(Packet * packet)
{
	//printf( "zq handleReqLotteryBegin " );
	if (!m_player)
		return;
	GoodCardManager cgoodcard;
	StreamReader reader ( packet->getData() );
	int  buygold = reader.get_int();
	
	char msgdata[256] = {0};
	BYTE result = RESULT_OK;
	int cardtype = 0;
	BYTE tmpcard[3] = {0};
	//参数检测
	if ( (buygold < 0) || (buygold > 200000) || (buygold%10000 != 0) )
	{
		return;
	}

	map< int, TigerConfig>::iterator iter = Config::instance()->m_tiger_data.find( 1 );
	INT64 systemwingold = 0;
	TigerRate *curtigerrate = NULL;
	if ( iter != Config::instance()->m_tiger_data.end() )
	{
		systemwingold = iter->second.systemwingold;
	}

	//确定选取概率
	for ( iter = Config::instance()->m_tiger_data.begin(); iter != Config::instance()->m_tiger_data.end(); iter++ )
	{
		curtigerrate = iter->second.rate;
		if ( ( (iter->second.mingold == -1) || (systemwingold >= iter->second.mingold) )  //-1表示无限制
			&& ((systemwingold < iter->second.maxgold) || (iter->second.maxgold == -1)) )
		{
			curtigerrate = iter->second.rate;
			break;
		}

	}
#if 0
	//test
	printf( "zq systemwingold = %d \r\n", systemwingold );
	printf( "zq buy tiger rate ===================\r\n" );
	for ( int i = 0; i < TIGER_CARD_TYPE_NUM; i++ )
	{
		printf( "%d     %d     %d \r\n", curtigerrate[i].type, curtigerrate[i].productrate, curtigerrate[i].paymentrate );
	}
#endif	
	//test
	int testcount = 1;
	INT64 testawardgold = 0;
	int testcardtype[CT_CARD_MAX] = {0};
	do 
	{
		if (m_player->get_user_gold() < buygold)
		{
			result = ERR_NOT_ENOUGH_GOLDS;
			break;
		}

		m_player->m_lottery_info.Clear();
		m_player->m_lottery_info.buygold = buygold;
		m_player->m_lottery_info.is_start = true;

		
		
		int ratenum = rand()%10000;

		int typeindex = 0;
		int totalsection = 0;
		for ( int i = 0; i < TIGER_CARD_TYPE_NUM; i++ )
		{
			totalsection += curtigerrate[i].productrate;
			//printf( "zq ratenum = %d, totalsection = %d\r\n", ratenum, totalsection );
			if ( ratenum < totalsection )
			{
				typeindex= i;
				break;
			}
		}
		
		cardtype = curtigerrate[typeindex].type;
#if 0//测试用
		int testcardtypelist[] = { 13,6,5,10,3,2,4,12,11,14 };
		cardtype = testcardtypelist[test_tiger_cradtype];
		test_tiger_cradtype = (test_tiger_cradtype+1)%10;  
#endif
		if ( (cardtype == CT_NO_HUA) ||(cardtype == CT_YI_HUA) ||(cardtype == CT_ER_HUA) )
		{
			cardtype = CT_SINGLE;
		}
		//printf( "cardtype = %d\r\n", cardtype );
		//m_player->m_game_logic.rand_card_list( tmpcard, 3 );
		do 
		{
			cgoodcard.InitCards();
			cgoodcard.GetCards( tmpcard, cardtype );//可以获取对应的类型牌,不过没有花色选择控制
			//printf( "\r\ntmpcard: %x %x %x \r\n", tmpcard[0], tmpcard[1], tmpcard[2] );
			int curcardtype = cgoodcard.GetCardType( tmpcard );
			//豹子如果是王牌则重新查找
			if ( (cardtype == CT_BAO_ZI) && (cgoodcard.IsWangPai(tmpcard)) )
			{
				continue;
			}
			//单牌如果是地龙则重新查找
			if ( (cardtype == CT_SINGLE) && (cgoodcard.IsDiLong(tmpcard)) )
			{
				continue;
			}
			break;
		} while ( 1 );
		if ( cardtype == CT_SINGLE )
		{
			int totalrate = curtigerrate[7].productrate + curtigerrate[8].productrate + curtigerrate[9].productrate;
			int nohuarate = curtigerrate[9].productrate*10000/totalrate;
			int nohuarandnum = rand()%10000;
			//printf( "zq nohuarate = %d nohuarandnum = %d\r\n", nohuarate, nohuarandnum );
			if ( nohuarandnum <= nohuarate )
			{
				int hualist[4] = {0};
				//无花
				for ( int i = 0; i < 3; i++ )
				{
					hualist[(tmpcard[i]&0xf0)>>4]++;
				}
				for ( int i = 0; i < 4; i++ )
				{
					if ( hualist[i] == 0 )
					{
						m_player->m_lottery_info.lucky_color = i;
					}
				}
				//printf( "zq hualist : %d  %d %d %d \r\n", hualist[0], hualist[1], hualist[2], hualist[3] );
				//printf( "zq  lucky_color = %d\r\n", m_player->m_lottery_info.lucky_color );
			}
			else
			{
				m_player->m_lottery_info.lucky_color = (tmpcard[rand()%3]&0xf0)>>4;
				//printf( "zq  2222lucky_color = %d\r\n", m_player->m_lottery_info.lucky_color );
			}
		}
		memcpy( m_player->m_lottery_info.lottery_card, tmpcard, 3 );

		//m_player->m_lottery_info.lucky_color = rand()%4;


		//test
		BYTE realtype = 0;
		int awardgold = buygold - m_player->GetLotteryRewardGold( realtype );
		testawardgold += awardgold;
		testcardtype[realtype]++;
		//printf( "zq tmpcard: %x %x %x realtype = %d  testcardtype[realtype] = %d\r\n", tmpcard[0], tmpcard[1], tmpcard[2], realtype, testcardtype[realtype] );	
	} while ( (--testcount) > 0 );
	//} while ( 0 );

#if 0
	printf( "============= test  tiger ================\r\n" );
	printf( "test award gold: %lld\r\n", testawardgold );
	printf( "wang pai:%d \r\n", testcardtype[CT_WANG_PAI] );
	printf( "bao   zi:%d \r\n", testcardtype[CT_BAO_ZI] );
	printf( "shun jin:%d \r\n", testcardtype[CT_SHUN_JIN] );
	printf( "di  long:%d \r\n", testcardtype[CT_DI_LONG] );
	printf( "shun zi :%d \r\n", testcardtype[CT_SHUN_ZI] );
	printf( "dui   zi:%d \r\n", testcardtype[CT_DOUBLE] );
	printf( "jin  hua:%d \r\n", testcardtype[CT_JIN_HUA] );
	printf( "er   hua:%d \r\n", testcardtype[CT_ER_HUA] );
	printf( "yi   hua:%d \r\n", testcardtype[CT_YI_HUA] );
	printf( "wu   hua:%d \r\n", testcardtype[CT_NO_HUA] );
	printf( "==========================================\r\n" );
#endif

	if ( result == RESULT_OK )
	{
		//发送到数据库
		SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		req->id = m_player->get_user_id();
		req->client		= this;
		req->req_type	= REQ_TYPE_TIGER;
		BYTE cardtype_ = 0;
		m_player->GetLotteryRewardGold( cardtype_ );
		char cardsstr[8] = {0};
		sprintf( cardsstr, "%02x%02x%02x", tmpcard[0], tmpcard[1], tmpcard[2]   );
		DBTigerReqMsg *pReqMsg = (DBTigerReqMsg*)req->sql;
		pReqMsg->uid = m_player->get_user_id();
		pReqMsg->cardtype = cardtype_;
		pReqMsg->buycount= buygold/10000;
		pReqMsg->buygold = -buygold;
		pReqMsg->reqtype = 1;
		pReqMsg->luckcolor = m_player->m_lottery_info.lucky_color;
		memcpy( pReqMsg->cards, cardsstr, 8 );
		//printf( "buygold = %d  pReqMsg->buygold = %d cardsstr=%s pReqMsg->cards = %s\r\n", buygold, pReqMsg->buygold, cardsstr, pReqMsg->cards );
		DataBaseReadThreadPool::instance()->pushQueue( req );
	}

}

void FrontClientHandler::handleReqLotterySwap(Packet * packet)
{
	if (!m_player)
		return;

	StreamReader reader ( packet->getData() );
	BYTE swap_index = reader.get_byte();
	int changenum = m_player->m_lottery_info.changenum;
	char msgdata[1024];
	BYTE result = RESULT_OK;
	do {
		if ( (swap_index < 1 || swap_index > 3) || (changenum < 1) ) {
			result = RESULT_FAILD;
			break;
		}

		if (m_player->get_user_gold() < m_player->m_lottery_info.GetNeedGold()) {
			result = ERR_NOT_ENOUGH_GOLDS;
			break;
		}

		if ( m_player->m_lottery_info.changenum <= 0 )
		{
			result = RESULT_FAILD;
			break;
		}

		bool need_random = false;
		BYTE rand_card = 0;
		do
		{
			rand_card = m_player->m_game_logic.get_rand_card();
			need_random = false;
			for (BYTE i = 1; i <= 3; ++i)
			{
				if (m_player->m_lottery_info.lottery_card[i-1] == rand_card)
				{
					need_random = true;
					break;
				}
			}
		} while ( need_random );

		m_player->m_lottery_info.lottery_card[swap_index-1] = rand_card;

	} while (0);

	if ( result == RESULT_OK )
	{
		//发送到数据库
		SQLReq * req = SQLMemoryPool::instance()->mallocReq();
		req->id = m_player->get_user_id();
		req->client		= this;
		req->req_type	= REQ_TYPE_TIGER;
		BYTE card_type = 0;
		m_player->GetLotteryRewardGold( card_type );//cgoodcard.GetCardType( m_player->m_lottery_info.lottery_card );

		char cardsstr[8] = {0};
		sprintf( cardsstr, "%02x%02x%02x", m_player->m_lottery_info.lottery_card[0], m_player->m_lottery_info.lottery_card[1], m_player->m_lottery_info.lottery_card[2]   );
		DBTigerReqMsg *pReqMsg = (DBTigerReqMsg*)req->sql;
		pReqMsg->uid = m_player->get_user_id();
		pReqMsg->cardtype = card_type;
		pReqMsg->buycount= m_player->m_lottery_info.buygold/10000;
		pReqMsg->buygold = -m_player->m_lottery_info.GetNeedGold();
		pReqMsg->changeindex = swap_index;
		pReqMsg->reqtype = 2;
		memcpy( pReqMsg->cards, cardsstr, 8 );
		DataBaseReadThreadPool::instance()->pushQueue( req );
	}
	else
	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_byte( m_player->m_lottery_info.lottery_card[swap_index-1] );
		stream_out.add_byte( swap_index );

		BYTE cardtype = 0;
		int rewardgold = m_player->GetLotteryRewardGold(cardtype);
		stream_out.add_byte( cardtype );
		stream_out.add_int( rewardgold );
		sendPacket( MSG_RESP_LOTTERY_SWAP, stream_out.get_buffer(), stream_out.get_buffer_len() );
	}
}

void FrontClientHandler::handleReqLotteryEnd(Packet * packet)
{
	if (!m_player)
		return;

	StreamReader reader ( packet->getData() );

	char msgdata[1024];
	BYTE result = RESULT_OK;

	BYTE card_type = 0;
	int awardgold = m_player->GetLotteryRewardGold( card_type );

	if ( m_player->m_lottery_info.is_start == false )
	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( ERR_TIGER_RECVING );
		sendPacket( MSG_RESP_LOTTERY_END, stream_out.get_buffer(), stream_out.get_buffer_len() );
		return;
	}

	m_player->m_lottery_info.is_start = false;
	
	//发送到数据库
	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	req->id = 0;
	req->client		= this;
	req->req_type	= REQ_TYPE_TIGER;

	char cardsstr[8] = {0};
	sprintf( cardsstr, "%02x%02x%02x", m_player->m_lottery_info.lottery_card[0], m_player->m_lottery_info.lottery_card[1], m_player->m_lottery_info.lottery_card[2]   );
	DBTigerReqMsg *pReqMsg = (DBTigerReqMsg*)req->sql;
	pReqMsg->uid = m_player->get_user_id();
	pReqMsg->cardtype = card_type;
	pReqMsg->buycount= m_player->m_lottery_info.buygold/10000;
	pReqMsg->buygold = awardgold;//赢取的金币数
	pReqMsg->reqtype = 3;
	memcpy( pReqMsg->cards, cardsstr, 8 );
	DataBaseReadThreadPool::instance()->pushQueue( req );

}



//数据库处理老虎机的结果
void FrontClientHandler::handleBuyTigerResult(SQLResp * resp)
{
	//printf( "zq === handleBuyTigerResult ===\r\n" );
	DBTigerRetMsg *pTigerMsg = (DBTigerRetMsg *)resp->data;
	int msgid = MSG_RESP_LOTTERY_BEGIN;
	if (!m_player)
	{
		return;
	}
	msgid += pTigerMsg->rsptype - 1;
	char msgdata[1024] = {0};
	if ( !resp->result  )
	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( ERR_TIGER_UNKNOW );
		sendPacket( msgid, stream_out.get_buffer(), stream_out.get_buffer_len() );
		//printf( "zq ERR_TIGER_UNKNOW \r\n" );
		return;
	}

	//数据库操作失败
	if ( pTigerMsg->result )
	{
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( ERR_TIGER_NO_GOLD );
		sendPacket( msgid, stream_out.get_buffer(), stream_out.get_buffer_len() );
		//printf( "zq ERR_TIGER_NO_GOLD \r\n" );
		return;
	}
	//printf( "zq pTigerMsg->rsptype = %d \r\n", pTigerMsg->rsptype  );
	map< int, TigerConfig>::iterator iter = Config::instance()->m_tiger_data.find( 1 );
	if ( iter != Config::instance()->m_tiger_data.end() )
	{
		iter->second.systemwingold -= pTigerMsg->buygold;
	}

	m_player->set_user_gold( pTigerMsg->gold);
	switch ( pTigerMsg->rsptype )
	{
	case 1:
		{
			StreamWriter stream_out(msgdata, sizeof(msgdata));
			stream_out.add_byte( true );
			stream_out.appand( m_player->m_lottery_info.lottery_card, MAX_COUNT);
			stream_out.add_byte( m_player->m_lottery_info.lucky_color );

			BYTE cardtype = 0;
			int rewardgold = m_player->GetLotteryRewardGold(cardtype);
			stream_out.add_byte( cardtype );
			stream_out.add_int( rewardgold );
			sendPacket( MSG_RESP_LOTTERY_BEGIN, stream_out.get_buffer(), stream_out.get_buffer_len() );

			break;
		}
	case 2:
		{
			//换牌成功
			m_player->m_lottery_info.changenum--;
			StreamWriter stream_out(msgdata, sizeof(msgdata));
			stream_out.add_byte( true );
			stream_out.add_byte( m_player->m_lottery_info.lottery_card[pTigerMsg->changeindex-1] );
			stream_out.add_byte( pTigerMsg->changeindex );

			BYTE cardtype = 0;
			int rewardgold = m_player->GetLotteryRewardGold(cardtype);
			stream_out.add_byte( cardtype );
			stream_out.add_int( rewardgold );
			sendPacket( MSG_RESP_LOTTERY_SWAP, stream_out.get_buffer(), stream_out.get_buffer_len() );
			break;
		}
	case 3:
		{
			BYTE result = RESULT_OK;
			BYTE card_type = 0;
			int awardgold = m_player->GetLotteryRewardGold( card_type );
			StreamWriter stream_out(msgdata, sizeof(msgdata));
			stream_out.add_byte( result );
			stream_out.add_byte( card_type );
			stream_out.add_int( awardgold );
			stream_out.add_int64(pTigerMsg->gold);
			sendPacket( MSG_RESP_LOTTERY_END, stream_out.get_buffer(), stream_out.get_buffer_len() );

			//中奖金币数大于 100000 发广播通知
			//printf( "awardgold = %d Config::instance()->get_send_horn_min_gold(MIN_GOLD_TYPE_TIGER) = %d\r\n", awardgold, Config::instance()->get_send_horn_min_gold(MIN_GOLD_TYPE_TIGER) );
			if( awardgold >= Config::instance()->get_send_horn_min_gold(MIN_GOLD_TYPE_TIGER) )
			{
				char szbuff[512] = {0};
				//snprintf(szbuff, sizeof(szbuff), "恭喜玩家【%s】在娱乐场老虎机赢得%d金币。", m_player->get_nick_name(), awardgold );
				const char *contentformat = Config::instance()->get_horn_format( HORN_FORMAT_TIGER );
				if ( contentformat )
				{
					snprintf(szbuff, sizeof(szbuff), contentformat, m_player->get_nick_name(), awardgold );
					StreamPacketBuilder::instance()->notifySystemBroadcast((u8_t *)szbuff, strlen(szbuff)+1, 0);
				}
			}
		}
		break;

	}

	//如果用户在桌子里面
	if ( m_player->getTable() )
	{
		StreamPacketBuilder::instance()->notifyUpdatePlayerGold( m_player->getTable(), m_player );
	}
}

void FrontClientHandler::handleReqEmailDelete(Packet * packet)
{
	StreamReader reader ( packet->getData() );
	int  email_id = reader.get_int();

	SQLReq * req = SQLMemoryPool::instance()->mallocReq();
	snprintf( req->sql , sizeof(req->sql) ,"call sp_user_email_delete(%u)", email_id );
	req->client		= this;
	req->req_type	= REQ_TYPE_EMAIL_DELETE;
	//WL(LL_DEV ,"player = %u handleReqEmailDelete sql=%s\n",m_player->get_user_id(),req->sql);
	DataBasePacketDataThread::instance()->push( req );
}


bool HttpLisentor::handle_open( int fd , InetAddr & address )
{
	HttpHandler * client = ( HttpHandler *) m_handler_pools.allocate();
	if ( client == NULL )
	{
		WL(LL_WARNING ,"get_event_scheduler()->alloc_event_object() faild\n");
		close( fd );
		return false;
	}
	client->set_address( address );
	client->set_handle( fd );
	if ( !get_event_scheduler()->register_handler( client ) ){

		WL(LL_WARNING ,"get_event_scheduler()->register_handler faild\n");
		m_handler_pools.free( client );
		return false ;
	}
	return true;
}

bool FrontLisentor::handle_open( int fd , InetAddr & address )
{
	//printf( "zq handle_open m_enable_connect = %d socketid = %d m_current_conn = %d  maxcon = %d\r\n", m_enable_connect, fd, m_current_conn, Config::instance()->m_max_connect_socket );
	//if ( m_current_conn > Config::instance()->m_max_connect_socket || !m_enable_connect )
	//{
	//	return false ;
	//}
	FrontClientHandler * client = ( FrontClientHandler *)get_event_scheduler()->alloc_event_object() ;
	if ( client == NULL )
	{
		WL(LL_WARNING ,"get_event_scheduler()->alloc_event_object() faild\n");
		close( fd );
		return false;
	}
	client->set_address( address );
	client->set_handle( fd );
	WL(LL_INFO , "handle_open, client = %p socketid = %d , \n", client, fd );
	//printf( "zq handle_open client = %x socketid = %d m_current_conn = %d\r\n", client, fd, m_current_conn );
	if ( !get_event_scheduler()->register_handler( client ) ){
		//printf("get_event_scheduler()->register_handler faild\n");
		WL(LL_WARNING ,"get_event_scheduler()->register_handler faild\n");
		get_event_scheduler()->free_event_object( client );
		return false ;
	}
	//m_current_conn ++ ;
	//printf("open ok=============================%d============\n",m_current_conn );
	return true;
}


void FrontClientHandler::SendSignInData(Player* pplayer)
{
	char msgdata[128] = {0};
	StreamWriter stream_out(msgdata, sizeof(msgdata));
	VECTOR_SIGN_IN_ITER iter;
	for ( iter = Config::instance()->m_sign_in_data.begin(); iter != Config::instance()->m_sign_in_data.end(); iter++ )
	{
		//printf( "SendSignInData: %d\n", *iter );
		stream_out.add_int( *iter );
	}

	sendPacket( MSG_CONFIG_SIGN_IN_DATA, stream_out.get_buffer(), stream_out.get_buffer_len() );
}

void FrontClientHandler::ReqSignIn( Packet* pPack )
{
	if ( m_player == NULL ) return ;
	//已领取发送领取消息
	UserInfo & refinfo = m_player->getUserInfo();
	if (refinfo.tody_get_login_box_count > 0) {
		StreamPacketBuilder::instance()->handleGetLoginRewardBox(m_player, false, 0);
		return;
	}
	refinfo.tody_get_login_box_count++;
	//发送
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_SIGNIN , this );
	req->id = m_player->get_user_id();
	*(int*)req->sql = m_player->get_user_id();
	//snprintf( req->sql , sizeof(req->sql) ,"call SP_User_SignIn(%d, %d)",m_player->get_user_id(), i );
	//printf( "req->sql = %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::RespSignInResult(SQLResp * resp)
{
	//printf( "===== RespSignInResult %d\r\n", *((int*)resp->data+1) );
	if (!m_player)
	{
		return;
	}
	if ( !resp->result  ) 
	{
		//领取错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_LOGIN_REWARD_BOX , ERR_REPEAT_OTAIN_AWARD  );
		return ;
	}
	UserInfo & refinfo = m_player->getUserInfo();
	int gold = *(int*)resp->data;
	m_player->set_user_gold( refinfo.user_score.gold + gold);

	StreamPacketBuilder::instance()->handleGetLoginRewardBox(m_player, true, gold);
}

//用户绑定账号
void FrontClientHandler::handleBindAccount(Packet* packet)
{
	if ( m_player == NULL )
	{
		return ;
	}
	StreamReader reader ( packet->getData() );
	
	const char * user_name	= reader.get_current_ptr();
	BYTE  length			= S_STRLEN( user_name ) ;
	reader.skip( length );

	const char * user_pwd	= reader.get_current_ptr();

	//发送
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_BIND_ACCOUNT , this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) ,"call SP_Bind_Account(%d, '%s', '%s' )",m_player->get_user_id(), user_name, user_pwd );
	//printf( "zq req->sql = %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}


//数据库返回绑定账号结果
void FrontClientHandler::handleBindAccountResult(SQLResp * resp)
{
	//printf( "zq handleBindAccountResult resp->result =%d ============ \r\n", resp->result );
	if (!m_player)
	{
		return;
	}
	if ( !resp->result  ) 
	{
		//数据库执行错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_BIND_ACCOUNT , ERR_BIND_ERROR  );
		return ;
	}
	
	DBBindUserAccount* pUserAccount = (DBBindUserAccount*)resp->data;
	if ( pUserAccount->result != 0 )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_BIND_ACCOUNT , pUserAccount->result  );
	}
	else
	{
		//更新数据
		m_player->set_user_name( pUserAccount->username );
		FrontClientHandler * handler = m_player->get_handler();
		StreamPacketBuilder::instance()->respOk( this ,MSG_RESP_BIND_ACCOUNT , NULL, 0  );
	}
}


//用户绑定手机
void FrontClientHandler::handleBindPhone(Packet* packet)
{
	if ( m_player == NULL )
	{
		return ;
	}
	StreamReader reader ( packet->getData() );

	const char * user_pwd	= reader.get_current_ptr();
	BYTE  length			= S_STRLEN( user_pwd ) ;
	reader.skip( length );

	const char * phone_num	= reader.get_current_ptr();
	//用户绑定赠送金币数
	DWORD givegold = Config::instance()->m_gamedataconfig[ DATA_CONFIG_BIND_PHONE ].valuelist[0];
	//发送
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_BIND_PHONE , this );
	req->id = m_player->get_user_id();
	DBBindPhoneMsg *reqMsg = (DBBindPhoneMsg *)req->sql;
	memcpy( reqMsg->telephone, phone_num, 16 );
	memcpy( reqMsg->pwd, user_pwd, 16 );
	reqMsg->result = 0;
	reqMsg->uid = m_player->get_user_id();
	reqMsg->givegold = givegold;
	DataBaseReadThreadPool::instance()->pushQueue( req );

}


//数据库返回绑定手机结果
void FrontClientHandler::handleBindPhoneResult(SQLResp * resp)
{
	//printf( "zq handleBindPhoneResult resp->result =%d ============ \r\n", resp->result );
	if (!m_player)
	{
		return;
	}
	
	if ( !resp->result  ) 
	{
		//数据库执行错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_BIND_PHONE , ERR_PHONE_BINDED  );
		return ;
	}
	else
	{
		//用户绑定赠送金币数
		DBBindPhoneMsg* pRetMsg = (DBBindPhoneMsg*)resp->data;
		if ( pRetMsg->result <= 0 )
		{
			StreamPacketBuilder::instance()->respError( this ,MSG_RESP_BIND_PHONE , ERR_PHONE_BINDED  );
			return;
		}
		DWORD givegold = pRetMsg->givegold;
		m_player->set_user_gold( m_player->get_user_gold() + givegold);
		if ( m_player->get_user_gold() != pRetMsg->curgold )
		{
			//以数据库的金币数为准
			m_player->set_user_gold( pRetMsg->curgold);
			printf( "zq golderror bind phone gold is error!\r\n" );
		}
		m_player->set_user_name( pRetMsg->telephone );
		m_player->set_phone_number( pRetMsg->telephone );

		FrontClientHandler * handler = m_player->get_handler();
		char msgdata[128] = {0};
		StreamWriter stream_out( msgdata, sizeof(msgdata) );
		stream_out.add_int( givegold );
		stream_out.add_int64( m_player->get_user_gold() );
		StreamPacketBuilder::instance()->respOk( this ,MSG_RESP_BIND_PHONE , stream_out.get_buffer(), stream_out.get_buffer_len()  );
	}
}

//老虎机配置
void FrontClientHandler::SendSlotConfig( Player *pplayer )
{
	SlotSwitchConfig *cfg = Config::instance()->get_slot_data();
	if (NULL == cfg)
	{
		printf( "tt get slot data err.... \r\n " );
		return;
	}

	BYTE count = cfg->channelid.size();

	char msgdata[128] = {0};
	StreamWriter stream_out(msgdata, sizeof(msgdata));
	stream_out.add_byte( count );
	for ( BYTE i = 0; i < count; i++ )
	{
		stream_out.add_int( cfg->channelid[i] );
	}
	sendPacket( MSG_NOTIFY_SLOT_CONFIG, stream_out.get_buffer(), stream_out.get_buffer_len() );
}

//时时彩配置
void FrontClientHandler::SendLotteryConfig( Player *pplayer )
{
	LotteryConfig *cfg = Config::instance()->get_lottery_data();
	if (NULL == cfg)
	{
		printf( "tt get lottery data err.... \r\n " );
		return;
	}

	BYTE count = cfg->channelid.size();

	char msgdata[128] = {0};
	StreamWriter stream_out(msgdata, sizeof(msgdata));
	stream_out.add_byte( cfg->multiplebet );
	stream_out.add_byte( count );
	for ( BYTE i = 0; i < count; i++ )
	{
		stream_out.add_int( cfg->channelid[i] );
	}
	sendPacket( MSG_LOTTERY_CONFIG, stream_out.get_buffer(), stream_out.get_buffer_len() );
}

void FrontClientHandler::SendGameDataConfig( Player *pplayer )
{
	if ( (!pplayer) || (pplayer->isNormalPlayer() == false) )
	{
		//printf( "==========================\r\n" );
		return;
	}
	char msgdata[1024*4] = {0};
	StreamWriter stream_out(msgdata, sizeof(msgdata));
	map< int, GameDataConfig>*pGameConfig =  &(Config::instance()->m_gamedataconfig);
	map< int, GameDataConfig>::iterator iter;
	//配置长度
	stream_out.add_int( pGameConfig->size() );
	printf( "pGameConfig->size() = %d\r\n", pGameConfig->size() );
	for ( iter = pGameConfig->begin(); iter != pGameConfig->end(); iter++ )
	{
		//金币配置
		stream_out.add_int( iter->first );
		GameDataConfig *pConfig = &(iter->second);
		int count = pConfig->valuelist.size();
		stream_out.add_int( count );
		//printf( "pConfig->goldlist.size() = %d\r\n", pConfig->valuelist.size() );
		for ( int j = 0; j < count; j++ )
		{
			stream_out.add_int( pConfig->valuelist[j] );
		}
	}

	//sendPacket( MSG_GAME_DATA_CONFIG, stream_out.get_buffer(), stream_out.get_buffer_len() );

	//发送商城信息
	memset( msgdata, 0, sizeof(msgdata) );
	int channelid = m_localInfo.channel;
	vector<MallGoodsInfo> mallinfo;
	Config::instance()->getmallgoodsdata( channelid, mallinfo);
	vector< MallGoodsInfo>::iterator goodsiter;
	stream_out.reset();
	stream_out.add_short( mallinfo.size() );
	//printf( "zq ==== mallinfo.size() = %d \r\n", mallinfo.size() );
	for ( goodsiter = mallinfo.begin(); goodsiter != mallinfo.end(); goodsiter++ )
	{
		stream_out.add_short( goodsiter->goodsid );
		//printf( "zq ==== goodsiter->goodsid = %d \r\n", goodsiter->goodsid );
		stream_out.add_int( goodsiter->price );
		stream_out.add_int( goodsiter->gold );
		stream_out.add_int( goodsiter->givegold );
		BYTE len = strlen( goodsiter->goodsname );
		stream_out.add_byte( len );
		stream_out.appand( goodsiter->goodsname, len );
		len = strlen( goodsiter->describe );
		stream_out.add_byte( len );
		stream_out.appand( goodsiter->describe, len );
		stream_out.add_short( goodsiter->roomid );
		stream_out.add_byte( goodsiter->bmalldisplay );
		stream_out.add_byte( goodsiter->bsms );
		stream_out.add_byte( goodsiter->isfirstpay );
		stream_out.add_byte( goodsiter->isPayed );
		len = strlen( goodsiter->remark );
		stream_out.add_byte( len );
		stream_out.appand( goodsiter->remark, len );
		len = strlen( goodsiter->remarkdesc );
		stream_out.add_byte( len );
		stream_out.appand( goodsiter->remarkdesc, len );
		//printf( "zq == mallinfo goodsid=%d,remarkdesc: %s \r\n", goodsiter->goodsid, goodsiter->remarkdesc );
	}
	//sendPacket( MSG_GAME_MALL_GOODS_CONFIG, stream_out.get_buffer(), stream_out.get_buffer_len() );
	
	//发送快充商品信息
	QuickGoodsInfo* quickgoods = Config::instance()->getquickgoodsdata();
	stream_out.reset();
	stream_out.add_short( quickgoods->goods.size() );
	//printf( "zq ==== quickgoods->goods.size() = %d \r\n", quickgoods->goods.size() );
	vector<MallGoodsInfo>::iterator quickgoodsiter;
	for ( quickgoodsiter = quickgoods->goods.begin(); quickgoodsiter != quickgoods->goods.end(); quickgoodsiter++ )
	{
		stream_out.add_short( quickgoodsiter->goodsid );
		//printf( "zq ==== quickgoodsiter->goodsid = %d \r\n", quickgoodsiter->goodsid );
		stream_out.add_int( quickgoodsiter->price );
		stream_out.add_int( quickgoodsiter->gold );
		stream_out.add_int( quickgoodsiter->givegold );
		BYTE len = strlen( quickgoodsiter->goodsname );
		stream_out.add_byte( len );
		stream_out.appand( quickgoodsiter->goodsname, len );
		len = strlen( quickgoodsiter->describe );
		stream_out.add_byte( len );
		stream_out.appand( quickgoodsiter->describe, len );
		stream_out.add_short( quickgoodsiter->roomid );
		stream_out.add_byte( quickgoodsiter->bmalldisplay );
		stream_out.add_byte( quickgoodsiter->bsms );
		stream_out.add_byte( quickgoodsiter->isfirstpay );
		stream_out.add_byte( quickgoodsiter->isPayed );
		len = strlen( quickgoodsiter->remark );
		stream_out.add_byte( len );
		stream_out.appand( quickgoodsiter->remark, len );
		len = strlen( quickgoodsiter->remarkdesc );
		stream_out.add_byte( len );
		stream_out.appand( quickgoodsiter->remarkdesc, len );
	}
	stream_out.add_byte( strlen(quickgoods->tips) );
	stream_out.appand( quickgoods->tips, strlen(quickgoods->tips) );
	//sendPacket( MSG_GAME_QUICK_GOODS_CONFIG, stream_out.get_buffer(), stream_out.get_buffer_len() );

	stream_out.reset();
	vector<LotteryDrawConifg>* plotteryconfig = Config::instance()->get_lotterydraw_config( 1 );
	vector<LotteryDrawConifg>::iterator lotteryiter;
	for ( lotteryiter = plotteryconfig->begin(); lotteryiter !=plotteryconfig->end(); lotteryiter++ )
	{
		stream_out.add_byte( lotteryiter->id );
		stream_out.add_byte( lotteryiter->type );
		stream_out.add_int( lotteryiter->value );
		stream_out.add_byte( strlen(lotteryiter->name) );
		stream_out.appand( lotteryiter->name, strlen(lotteryiter->name) );
	}
	sendPacket( MSG_LOTTERYDRAW_CONFIG, stream_out.get_buffer(), stream_out.get_buffer_len() );

	stream_out.reset();
	map<int, VipConfig>::iterator vipiter;
	for ( vipiter = Config::instance()->m_vipconfigmap.begin(); vipiter != Config::instance()->m_vipconfigmap.end(); vipiter++ )
	{
		stream_out.add_int( vipiter->second.transfermaxgold );
	}
	sendPacket( MSG_VIP_MAX_TRANSFER_GOLD, stream_out.get_buffer(), stream_out.get_buffer_len() );

	SendLotteryConfig( m_player );
	SendSlotConfig( m_player );
}


//修改用户昵称
void FrontClientHandler::handleUpdateNickName( Packet* packet )
{
	if ( m_player == NULL )
	{
		return ;
	}
	char nickname[32] = {0};
	StreamReader reader( packet->getData() );
	BYTE nicknamelen = reader.get_short();
	nicknamelen = (nicknamelen >= 32) ? 31 : nicknamelen;
	char *pStart = reader.get_current_ptr();
	//printf( "nickname = %s  nicknamelen = %d\r\n", pStart, nicknamelen );
	char *pEnd = reader.get_current_ptr() + nicknamelen - 1;
	while ( (*pStart == ' ') || (*pStart == '\t') || (*pStart == '\n') )
	{
		pStart++;
	}
	while ( (*pEnd == ' ') || (*pEnd == '\t') || (*pEnd == '\n') )
	{
		pEnd--;
	}
	if ( (nicknamelen == 0) || (pEnd - pStart == 0)  )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_UPDATE_NICKNAME , ERR_SYSTEM  );
		return;
	}
	//过虑掉中间的'\n'
	int templen = 0;
	while ( pStart <= pEnd )
	{
		if ( *pStart == '\n' )
		{
			break;
		}
		nickname[templen++] = *pStart++;
	}
	//memcpy( nickname, pStart, pEnd - pStart );
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_UPDATE_NICKNAME, this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) , "call SP_UpdateNickName( %u, '%s' )",  m_player->get_user_id(), nickname );
	//printf( "zq  handleUpdateNickName req->sql = %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleUpdateNickNameResult(SQLResp * resp)
{
	if (!m_player)
	{
		return;
	}

	if ( !resp->result  ) 
	{
		//printf( "handleUpdateNickNameResult return error !\r\n" );
		//数据库执行错误
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_UPDATE_NICKNAME , ERR_SYSTEM  );
		return ;
	}
	
	TUpdate_Nick_Name *pMsg = (TUpdate_Nick_Name*)resp->data;
	if (pMsg->result !=  0 )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RESP_UPDATE_NICKNAME , pMsg->result);
		return;
	}
	m_player->set_nick_name( pMsg->szName);
	m_player->set_user_gold(m_player->get_user_gold() - pMsg->gold);
	char senddata[128] = {0};
	StreamWriter stream_out(senddata,sizeof(senddata));
	stream_out.add_byte( RESULT_OK );
	stream_out.add_int64(m_player->get_user_gold());
	sendPacket( MSG_RESP_UPDATE_NICKNAME, stream_out.get_buffer(), stream_out.get_buffer_len() );
}

void FrontClientHandler::handleTransferGold( Packet *packet )
{
	if ( m_player == NULL )
	{
		return ;
	}
	int transfer_time = time(NULL);
	if(m_last_transfer_end_time > 0 && (transfer_time - m_last_transfer_end_time ) < 5)
	{
		WL(LL_INFO,"nUserID:%d  transfer_time=%d m_last_transfer_end_time=%d  time = %d \n",m_player->get_user_id(),transfer_time, m_last_transfer_end_time, transfer_time - m_last_transfer_end_time);
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_TRANSFER_GOLD , ERROR_TRANSFER_TO_FAST  );
		return;
	}
	StreamReader reader( packet->getData() );
	INT64 transfergold = reader.get_uint();
	DWORD touserid = reader.get_uint();
	UserInfo userinfo = m_player->getUserInfo();
	if ( (transfergold <= 0 ) || (m_player->get_user_enable_gold() < transfergold) || (touserid < 0) )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_TRANSFER_GOLD , ERROR_TRANSFER_UNKNOW  );
		return;
	}
	
	//查询用户vip级别的转账最大金币数
	INT64  maxdepositgold = Config::instance()->m_vipconfigmap[userinfo.viplevel].transfermaxgold;
	if ( transfergold > maxdepositgold )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_TRANSFER_GOLD , ERROR_TRANSFER_LESS_LEVEL  );
		return;
	}


	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_STRANSFER_GOLD, this );
	req->id = m_player->get_user_id();
	DBTransferGoldMsg *pMsg = (DBTransferGoldMsg*)req->sql;
	pMsg->result = 0;
	pMsg->userid = m_player->get_user_id();
	pMsg->gold = transfergold;
	pMsg->touserid = touserid;
	pMsg->togold = 0;
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::handleTransferGoldResult( SQLResp * resp)
{
	//printf( "zq handleTransferGoldResult === \r\n" );
	if (!m_player)
	{
		return;
	}

	if ( !resp->result  ) 
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_TRANSFER_GOLD , ERROR_TRANSFER_UNKNOW  );
		return ;
	}
	DBTransferGoldMsg* pRetMsg = (DBTransferGoldMsg*)resp->data;
	//printf( "zq pRetMsg->result = %d\r\n", pRetMsg->result );
	if ( pRetMsg->result != 0 )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_TRANSFER_GOLD , pRetMsg->result  );
		return ;
	}
	//修改用户金币币
	m_player->set_user_gold( m_player->get_user_gold() - pRetMsg->gold);
	char senddata[128] = {0};
	StreamWriter stream_write(senddata, sizeof(senddata) );
	stream_write.add_byte( 1 );//结果
	stream_write.add_uint( pRetMsg->touserid );
	stream_write.add_uint( pRetMsg->gold );
	stream_write.add_int64( m_player->get_user_gold() );
	sendPacket( MSG_RSP_TRANSFER_GOLD, stream_write.get_buffer(), stream_write.get_buffer_len() );
	

	//查找被送用户数据
	FrontClientHandler* touserhandle = ActiveConnsList::instance()->find( pRetMsg->touserid );
	Player* player = NULL;
	if ( touserhandle)
	{
		player = touserhandle->getPlayer();
		if ( !player )
		{
			return;
		}
		player->set_user_gold( touserhandle->getPlayer()->get_user_gold() + pRetMsg->togold);
		char senddata[128] = {0};
		StreamWriter stream_write(senddata, sizeof(senddata));
		stream_write.add_byte( 1 );//结果
		stream_write.add_uint( pRetMsg->userid );
		stream_write.add_uint( pRetMsg->togold );
		stream_write.add_int64( touserhandle->getPlayer()->get_user_gold() );
		touserhandle->sendPacket( MSG_NOTIFY_TRANSFER_GOLD, stream_write.get_buffer(), stream_write.get_buffer_len() );
		
	}
	m_last_transfer_end_time = time(NULL);


}

void FrontClientHandler::handleTransferGoldRecord( Packet *packet )
{
	if ( m_player == NULL )
	{
		return ;
	}
	StreamReader reader( packet->getData() );
	UserInfo userinfo = m_player->getUserInfo();
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_STRANSFER_GOLD_RECORD, this );
	req->id = m_player->get_user_id();
	*(DWORD*)req->sql = m_player->get_user_id();
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::OnDBTransferGoldRecord( SQLResp * resp )
{
	if (!m_player)
	{
		return;
	}

	if ( !resp->result  ) 
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_TRANSFER_GOLD_RECORD , ERROR_TRANSFER_UNKNOW  );
		return ;
	}
	DBTransferGoldRectList *pRetMsg = (DBTransferGoldRectList *)resp->data;
	char senddata[1024] = {0};
	StreamWriter stream_write(senddata, sizeof(senddata));
	stream_write.add_byte( pRetMsg->len );
	for ( int i = 0; i < pRetMsg->len; i++ )
	{
		stream_write.add_uint( pRetMsg->data[i].touserid );
		stream_write.add_uint( pRetMsg->data[i].fromuserid );
		stream_write.add_uint( pRetMsg->data[i].transfergold );
		stream_write.add_uint( pRetMsg->data[i].time );
		//printf( "zq transfer %u %u %d %u \r\n", pRetMsg->data[i].touserid, pRetMsg->data[i].fromuserid, pRetMsg->data[i].transfergold, pRetMsg->data[i].time  );
		//stream_write.appand( pRetMsg->data[i].nicknmae, S_STRLEN(pRetMsg->data[i].nicknmae) );
	}
	sendPacket( MSG_RSP_TRANSFER_GOLD_RECORD, stream_write.get_buffer(), stream_write.get_buffer_len() );
}


//用户聊天消息
void FrontClientHandler::handleFriendChat( Packet *packet )
{
	if (!m_player)
	{
		return;
	}

	StreamReader reader( packet->getData() );
	DWORD touserid = reader.get_uint();
	DWORD id = reader.get_uint();
	const char * content	= reader.get_current_ptr();
	int  length			= S_STRLEN( content ) ;
	reader.skip( length );

	//查找用户是否在线
	FrontClientHandler *touserhandle = ActiveConnsList::instance()->find( touserid );
	if ( touserhandle )
	{
		char senddata[512] = {0};
		StreamWriter stream_writer(senddata, sizeof(senddata));
		stream_writer.add_uint( m_player->get_user_id() );
		stream_writer.add_uint( time(NULL) );
		stream_writer.appand( content, length );
		touserhandle->sendPacket( MSG_NOTIFY_FRIEND_RECV_MESSAGE, stream_writer.get_buffer(), stream_writer.get_buffer_len() );
		//printf( "zq friend is online send data stream_writer.get_buffer_len() = %d content = -%s- length = %d packetlen = %d\r\n", stream_writer.get_buffer_len(), content, length, packet->getDataLen() );
	}
	else
	{
		//保存到数据库
		SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_EXECUTE_COMMOND, NULL );
		req->id = m_player->get_user_id();
		snprintf( req->sql , sizeof(req->sql) , "call SP_Chat_Save_Chat_Message( %u, %u, '%s' )",  touserid, m_player->get_user_id(), content );
		DataBaseReadThreadPool::instance()->pushQueue( req );
		//printf( "zq friend is offline save data  req->sql = %s\r\n", req->sql );
	}
	sendPacket( MSG_RSP_FRIEND_SEND_MESSAGE, &id, sizeof(id) );
}

//读取用户消息记录
void FrontClientHandler::ReadFriendChatRecord( Packet *packet )
{
	if (!m_player)
	{
		return;
	}

	StreamReader reader( packet->getData() );
	DWORD frienduserid = reader.get_uint();
	//保存到数据库
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_GET_CHAT_MESSAGE, this );
	req->id = m_player->get_user_id();
	USER_REQ_CHAT_DATA* reqmsg = (USER_REQ_CHAT_DATA*)req->sql;
	reqmsg->userid = m_player->get_user_id();
	reqmsg->fromuserid = frienduserid;
	
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

//读取用户消息记录
void FrontClientHandler::OnDBReadFriendChatRecord( SQLResp * resp )
{

	if (!m_player)
	{
		return;
	}
	//
	USER_CHAT_RECORD_ARRAY *pRetMsg = (USER_CHAT_RECORD_ARRAY*)resp->data;
	char senddata[1024*8] = {0};
	StreamWriter stream_write(senddata, sizeof(senddata));
	stream_write.add_uint( pRetMsg->fromuserid );
	stream_write.add_byte( pRetMsg->count );
	for ( int i = 0; i < pRetMsg->count; i++ )
	{
		stream_write.add_uint( pRetMsg->list[i].time );
		stream_write.add_byte( strlen( pRetMsg->list[i].content ) );
		stream_write.appand( pRetMsg->list[i].content, strlen( pRetMsg->list[i].content ) );
		//printf( "zq pRetMsg->list[i].content = %s len = %d\r\n", pRetMsg->list[i].content, strlen( pRetMsg->list[i].content ) );
	}
	sendPacket( MSG_RSP_HISTORY_MESSAGE, stream_write.get_buffer(), stream_write.get_buffer_len() );
}


void FrontClientHandler::handleLotteryDraw( Packet *packet )
{
	int basegold = 10000;
	int awardgoodsid = 4;//默认最小金币数 防止加载配置出错
	int lotteryver = 1;
	StreamReader reader( packet->getData() );
	DBLotteryDrawMsg Msg = {0};
	Msg.type = reader.get_byte();
	Msg.times = reader.get_byte();
	lotteryver = reader.get_byte();
	DBLotteryDrawMsg* pMsg = &Msg;//修改
	if ( !m_player)
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_LOTTERY_DRAW , ERROR_LOTTERYDRAW_UNKNOW  );
		return;
	}

	//参数验证
	if (
		( Msg.type < 0 || Msg.type > 2 ) ||		//抽奖类型不对
		( (Msg.times != 1) && (Msg.times != 2) && (Msg.times != 5) && (Msg.times != 10) ) || //连抽次数不对
		( lotteryver != 1 )
		)
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_LOTTERY_DRAW , ERROR_LOTTERYDRAW_UNKNOW  );
		return;
	}


	//修正参数错误
	if ( pMsg->type == 1 )
	{
		pMsg->times = 1;
	}

	//用户是否能抽奖
	if ( (pMsg->type == 1) && (m_player->get_lotterydraw_count() <= 0) )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_LOTTERY_DRAW , ERROR_LOTTERYDRAW_NO_LOTTERY  );
		return;
	}

	if ( (pMsg->type == 2) && (m_player->get_user_enable_gold() < basegold*pMsg->times) )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_LOTTERY_DRAW , ERROR_LOTTERYDRAW_NO_GOLD  );
		return;
	}

	if ( pMsg->type == 1 )
	{
		m_player->set_lotterydraw_count( m_player->get_lotterydraw_count() - 1 );
	}
	else if ( pMsg->type == 2 )
	{
		m_player->set_user_gold( m_player->get_user_gold() - basegold*pMsg->times);
	}
	vector<LotteryDrawConifg>* pConfig = Config::instance()->get_lotterydraw_config( lotteryver );
	int randnum = rand()%10000;
	int totalrate = 0;
	if ( pConfig == NULL )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_LOTTERY_DRAW , ERROR_LOTTERYDRAW_NO_LOTTERY  );
		return;
	}
	vector<LotteryDrawConifg>::iterator iter;
	for ( iter = pConfig->begin(); iter != pConfig->end(); iter++ )
	{
		totalrate += iter->rate[pMsg->type - 1];
		//printf( " randnum = %d, totalrate = %d goodsid = %d\r\n", randnum, totalrate, iter->id );
		if ( randnum < totalrate )
		{
			awardgoodsid = iter->id;
			break;
		}
	}

	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_LOTTERYDRAW, this );
	req->id = m_player->get_user_id();
	DBLotteryDrawMsg *pLotteryMsg = (DBLotteryDrawMsg*)req->sql;
	pLotteryMsg->goodsid = awardgoodsid;
	pLotteryMsg->type = pMsg->type;
	pLotteryMsg->useid = m_player->get_user_id();
	pLotteryMsg->times = pMsg->times;
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::OnDBLotteryDraw( SQLResp* resp )
{
	int basegold = 10000;
	if (!m_player)
	{
		return;
	}

	if ( !resp->result  ) 
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_LOTTERY_DRAW , ERROR_TRANSFER_UNKNOW  );
		return ;
	}
	DBLotteryDrawRetMsg *pMsg = (DBLotteryDrawRetMsg*)resp->data;
	if ( pMsg->result != 0 )
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_LOTTERY_DRAW , pMsg->result  );
		//恢复用户数据
		if ( pMsg->type == 1 )
		{
			m_player->set_lotterydraw_count( m_player->get_lotterydraw_count() + 1 );
		}
		else if ( pMsg->type == 2 )
		{
			m_player->set_user_gold( m_player->get_user_gold() + basegold*pMsg->times);
		}
		return;
	}

	//抽奖成功
	int changegold = 0;
	if ( pMsg->goodstype == LOTTERYDRAW_GOODS_TYPE_GOLD )
	{
		changegold = pMsg->changevalue;
	}
	if ( pMsg->goodstype == LOTTERYDRAW_GOODS_TYPE_CAR )
	{
		m_player->set_car( m_player->get_car() + pMsg->changevalue );
	}
	else if ( pMsg->goodstype == LOTTERYDRAW_GOODS_TYPE_YACHT )
	{
		m_player->set_yacht( m_player->get_yacht() + pMsg->changevalue );
	}
	//printf( "zq transfer %lld  %d %lld %d %lld\r\n", m_player->get_user_enable_gold(), changegold, m_player->get_user_gold(), m_player->get_lotterydraw_count(), pMsg->curgold );
	m_player->set_user_gold( pMsg->curgold  + changegold);
	if ( m_player->get_user_enable_gold() != pMsg->curgold )
	{
		m_player->set_user_gold( pMsg->curgold);
	}
	char senddata[1024] = {0};
	StreamWriter stream_write(senddata, sizeof(senddata));
	stream_write.add_byte( 1 );	//成功
	stream_write.add_uint( pMsg->goodsid );	//奖品ID
	stream_write.add_int64( m_player->get_user_gold() );	//用户当前金币数
	stream_write.add_uint( m_player->get_lotterydraw_count() );//用户当前抽奖券
	stream_write.add_byte( pMsg->times );
	//printf( "zq transfer %d %lld %d \r\n", changegold, m_player->get_user_gold(), m_player->get_lotterydraw_count() );
	sendPacket( MSG_RSP_LOTTERY_DRAW, stream_write.get_buffer(), stream_write.get_buffer_len() );

	//发送喇叭
	if ( pMsg->goodstype == 2 )
	{
		char szbuff[512] = {0};
		//snprintf(szbuff, sizeof(szbuff), "鸿运高照,恭喜玩家\"%s\"在大转轮中获得%d元话费券", m_player->get_nick_name(), pMsg->changevalue );
		const char *contentformat = Config::instance()->get_horn_format( HORN_FORMAT_DRAW_TELFARE );
		if ( contentformat )
		{
			snprintf(szbuff, sizeof(szbuff), contentformat, m_player->get_nick_name(), pMsg->changevalue );
			StreamPacketBuilder::instance()->notifySystemBroadcast((u8_t *)szbuff, strlen(szbuff)+1, m_player->get_user_id());
		}
		
	}
	else
	{
		int mingold = Config::instance()->get_send_horn_min_gold( MIN_GOLD_TYPE_LOTTERYDRAW );
		if ( changegold >= mingold )
		{
			char szbuff[512] = {0};
			const char *contentformat = Config::instance()->get_horn_format( HORN_FORMAT_DRAW_GOLD );
			if ( contentformat )
			{
				snprintf(szbuff, sizeof(szbuff), contentformat, m_player->get_nick_name(), pMsg->changevalue );
				StreamPacketBuilder::instance()->notifySystemBroadcast((u8_t *)szbuff, strlen(szbuff)+1, m_player->get_user_id());
			}
			//snprintf(szbuff, sizeof(szbuff), "鸿运高照,恭喜玩家\"%s\"在大转轮中获得%d金币", m_player->get_nick_name(), pMsg->changevalue );
		}
	}
}

void FrontClientHandler::handleGetWealthFromDB( Packet* packet )
{
	if (!m_player)
	{
		return;
	}

	//
	//保存到数据库
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_GET_USER_WEALTH, this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) , "SELECT gold, diamond, ticket, \'\' AS \'message\' FROM user_info WHERE user_id = %u;",  m_player->get_user_id() );
	//printf( "zq handleGetWealthFromDB sql : %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void FrontClientHandler::OnDBUpdateWealth( SQLResp* resp  )
{
	if (!m_player)
	{
		return;
	}
	//printf( "zq OnDBUpdateWealth resp->result = %d\r\n", resp->result );
	if ( !resp->result  ) 
	{
		StreamPacketBuilder::instance()->respError( this ,MSG_RSP_UPDATE_WEALTH , ERR_UNKOWN  );
		return ;
	}
	DB_GET_USER_WEALTH* pRetMsg = (DB_GET_USER_WEALTH*)resp->data;
	m_player->set_user_gold( pRetMsg->gold);
	m_player->set_user_ticket( pRetMsg->ticket );
	m_player->set_diamond( pRetMsg->diamond );
	//printf( "zq pRetMsg->gold = %lld pRetMsg->ticket = %d pRetMsg->diamond = %d resp->req_type = %d pRetMsg->message = %s\r\n", 
		//pRetMsg->gold,pRetMsg->ticket, pRetMsg->diamond, resp->req_type, pRetMsg->message );
	if ( resp->req_type == REQ_TYPE_GET_USER_WEALTH_EX )
	{
		//是否发送email
		if ( strlen(pRetMsg->message) > 1 )
		{
			char senddata[1024] = {0};
			StreamWriter mail_stream_out(senddata, sizeof(senddata));
			mail_stream_out.add_byte( 7 );
			int msglen = strlen(pRetMsg->message);
			mail_stream_out.add_short(msglen);
			mail_stream_out.appand(pRetMsg->message, msglen);
			//printf( "==========MSG_NOTIFY_ADD_EMAIL=========\r\n" );
			sendPacket(MSG_NOTIFY_ADD_EMAIL, senddata, mail_stream_out.get_buffer_len());
		}
		//下发给用户金币变化
		char senddata[128] = {0};
		StreamWriter stream_write( senddata, sizeof(senddata) );
		stream_write.add_byte( 1 );
		stream_write.add_int64( pRetMsg->gold );
		stream_write.add_int( pRetMsg->diamond );
		stream_write.add_int( pRetMsg->ticket );
		stream_write.add_byte( 1 );//类型  1推荐
		sendPacket( MSG_RSP_UPDATE_WEALTH, stream_write.get_buffer(), stream_write.get_buffer_len() );
		StreamPacketBuilder::instance()->notifyUpdatePlayerGold( m_player->getTable(), m_player, false );

	}

	/*用户在百人房，通知金币更新*/
	if(m_player->GetCurRoomID() == ROOM_CONFI_ID_BRC)
	{
		CBrcMsgHandle::instance()->ExchangeGoldUpdate(m_player->get_user_id(), pRetMsg->gold );
	}
}


void FrontClientHandler::OnDBBuyOrSellGoods( SQLResp* resp  )
{
	if (!m_player)
	{
		return;
	}
	DB_BUY_SELLGOODS_DATA_RET *pMsg = (DB_BUY_SELLGOODS_DATA_RET*)resp->data;
	m_player->set_user_gold( pMsg->gold);
	m_player->set_user_ticket( pMsg->ticket );
	m_player->set_diamond( pMsg->diamond );
	//printf( "zq pRetMsg->gold = %lld pRetMsg->ticket = %d pRetMsg->diamond = %d\r\n", pMsg->gold,pMsg->ticket, pMsg->diamond );
	if ( strlen( pMsg->emailcontent ) > 0  )
	{
		char senddata[1024] = {0};
		StreamWriter stream_write(senddata, sizeof(senddata));
		stream_write.add_int64( pMsg->gold );
		stream_write.add_uint( pMsg->diamond );
		stream_write.add_uint( pMsg->ticket );
		stream_write.add_byte( strlen( pMsg->emailcontent ) );
		stream_write.appand( pMsg->emailcontent, strlen( pMsg->emailcontent ) );
		sendPacket( MSG_RSP_SELLGOODS_BUY, stream_write.get_buffer(), stream_write.get_buffer_len() );
	}
}

void FrontClientHandler::handleDeleteTable( Packet *packet )
{
	if ( !m_player )
	{
		return ;
	}

	//房间名称
	TableBase * table = PrivateTableManager::instance()->exitsCreator( m_player->get_user_id() )  ;
	if ( !table )
	{
		StreamPacketBuilder::instance()->respError( m_player, MSG_RESP_DELETE_PRI_TABLE, ERROR_DELETE_TABLE_NO_EXIST );//只有桌子不存在的错误
		return;
	}

	if ( table->getPlayerCount() > 0 )
	{
		StreamPacketBuilder::instance()->respError( m_player, MSG_RESP_DELETE_PRI_TABLE, ERROR_DELETE_TABLE_HAS_PLAYER );//只有桌子不存在的错误
		return;
	}
	//发送到数据

	//PrivateTableManager::instance()->ReleasePrivTable( table );
	//保存到数据库
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_DELETE_TABLE, this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) , "DELETE FROM priv_playing_tables WHERE user_id = %u;",  m_player->get_user_id() );
	//printf( "zq handleDeleteTable sql : %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}


void FrontClientHandler::OnDBDeleteTable( SQLResp *resp )
{
	if ( !m_player )
	{
		return ;
	}
	if ( resp->result == 0 )
	{
		StreamPacketBuilder::instance()->respError( m_player, MSG_RESP_DELETE_PRI_TABLE, ERROR_DELETE_TABLE_SYSTEM_ERR );//
		return;
	}
	TableBase * table = PrivateTableManager::instance()->exitsCreator( m_player->get_user_id() )  ;
	if ( !table )
	{
		StreamPacketBuilder::instance()->respError( m_player, MSG_RESP_DELETE_PRI_TABLE, ERROR_DELETE_TABLE_NO_EXIST );//只有桌子不存在的错误
		return;
	}
	PrivateTableManager::instance()->ReleasePrivTable( table );
	char senddata[64] = {0};
	StreamWriter stream_write(senddata, sizeof(senddata));
	stream_write.add_byte( RESULT_OK );
	stream_write.add_int( table->getTableOwner() );
	sendPacket( MSG_RESP_DELETE_PRI_TABLE, stream_write.get_buffer(), stream_write.get_buffer_len() );
}

void FrontClientHandler::ClearLastDayVar()
{
	if ( !m_player )
	{
		return ;
	}

	DWORD daystarttime = time(NULL) - (time(NULL) + 3600*8)%(3600*24);	//0点时间
	//printf( "m_player->getUserInfo().last_login_time = %d daystarttime = %d\r\n", m_player->getUserInfo().last_login_time, daystarttime );
	if ( m_player->getUserInfo().last_login_time >= daystarttime )
	{
		return;
	}
	//printf( "m_player->getUserInfo().last_login_time = %d daystarttime = %d\r\n", m_player->getUserInfo().last_login_time, daystarttime );
	//保存到数据库
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_CLEAR_LASTDAY_VAR, this );
	req->id = m_player->get_user_id();
	snprintf( req->sql , sizeof(req->sql) , "call SP_Clear_LastDay_Data( %d ) ",  m_player->get_user_id() );
	//printf( "zq ClearLastDayVar sql : %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}


void FrontClientHandler::onDBGetGold(SQLResp * resp)
{
	if(!m_player)
		return;
	if ( resp->result == 0 )
		return;

	DB_ENTER_ROOM_CHECK *pMsg = (DB_ENTER_ROOM_CHECK*)resp->data;
	
	if(pMsg->gold!= m_player->get_user_gold())
	{
		WL(LL_ERROR,"nUserID:%d gold un legel now gold:%lld db gold:%lld \n", m_player->get_user_id(), m_player->get_user_gold(), pMsg->gold);

		m_player->set_user_gold(pMsg->gold);
		StreamPacketBuilder::instance()->notifyUpdatePlayerGold( m_player->getTable(), m_player );
	}
}

void FrontClientHandler::onDbGetDuobaoNotify(SQLResp *resp)
{
	if(!m_player)
		return;

	if(resp->result == 0)
		return;

	DB_GET_DUOBAO_NOTIFY *pMsg = (DB_GET_DUOBAO_NOTIFY*)resp->data;
	if(pMsg->nResult != 0)
		return;
	char senddata[1024] = {0};
	StreamWriter mail_stream_out(senddata, sizeof(senddata));
	int msglen = strlen(pMsg->szContent);
	mail_stream_out.add_short(msglen);
	mail_stream_out.appand(pMsg->szContent, msglen);
	this->sendPacket(MSG_NOTIFY_DUOBAO, mail_stream_out.get_buffer(), mail_stream_out.get_buffer_len());
	
}

void FrontClientHandler::handleShareReward(int scene_id, int type)
{
	if (!m_player)
		return;
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_SHARE_REWARD, this );
	req->id = m_player->get_user_id();
	snprintf(req->sql, sizeof(req->sql), "call SP_GET_DAILY_SHARE_REWARD(%d, %d,%d)", m_player->get_user_id(), scene_id, type);
	DataBaseReadThreadPool::instance()->pushQueue( req );
}


void FrontClientHandler::onDbGetShareReward(SQLResp * resp)
{
	
	if(!m_player)
		return;

	char senddata[1024] = {0};
	StreamWriter stream_out(senddata, sizeof(senddata));
	TDB_DAILY_SHARE_REWARD *pMsg = (TDB_DAILY_SHARE_REWARD*)resp->data;
	if ( resp->result == 0 )
	{
		stream_out.add_byte(RESULT_FAILD);
		this->sendPacket(MSG_SHARE_REWARD_RPSE, stream_out.get_buffer(), stream_out.get_buffer_len());
		return;
	}

	if(pMsg->type == is_can_share_wechat)
	{
		stream_out.add_byte(RESULT_OK);
		stream_out.add_byte(pMsg->type);
		stream_out.add_int(pMsg->result);
		stream_out.add_int(pMsg->money);
	}
	else if (pMsg->type == get_share_reward_req)
	{
		stream_out.add_byte(RESULT_OK);
		stream_out.add_byte(pMsg->type);
		stream_out.add_int(pMsg->money);
		stream_out.add_byte(pMsg->scene_id);
	}

	this->sendPacket(MSG_SHARE_REWARD_RPSE, stream_out.get_buffer(), stream_out.get_buffer_len());
	
	if( pMsg->money > 0 )
	{
			m_player->set_user_gold(m_player->get_user_gold() + pMsg->money);
	}
}


void FrontClientHandler::OnDBClearLastDayVar( SQLResp *resp )
{
	//printf( "zq OnDBClearLastDayVar resp->result = %d \r\n", resp->result );
	if ( !m_player )
	{
		return ;
	}
	if ( resp->result == 0 )
	{
		return;
	}

	DB_CLEAR_LASTDAY_VAR *pMsg = (DB_CLEAR_LASTDAY_VAR *)resp->data;
	if ( pMsg->result != 0 )
	{
		m_player->getUserInfo().last_login_time = pMsg->logintime;
		return;
	}
	m_player->InitEveryDayVar( pMsg );
	//发送给客户
	//printf( "MSG_NOTIFY_REFRESH_LOGIN ==== \r\n" );
	sendPacket( MSG_NOTIFY_REFRESH_LOGIN, pMsg, sizeof(DB_CLEAR_LASTDAY_VAR) );

}

void FrontClientHandler::handleClientReportIP(Packet *packet)
{
#if 0
	char ip[32] = {0};
	StreamReader reader( packet->getData() );
	BYTE nLen = reader.get_byte();
	if(nLen >= 32)
	{
		nLen = nLen -1;
	}
	memcpy(ip, reader.get_current_ptr(), nLen);
	reader.skip( nLen ); 
	
	struct in_addr addr;
	inet_aton(ip, &addr);
	DWORD nIp = htonl(addr.s_addr);
	
	int present = 0 ;
	writeLoginLog(nIp,  getClientId(), m_localInfo ,present);
#endif
	
}

void FrontClientHandler::handleGetUserDuoBaoNotfyContent(int nUserID)
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_DUOBAO, this );
	req->id = nUserID;
	req->client = this;
	memset( req->sql, 0, sizeof(req->sql) );
	snprintf(req->sql, sizeof(req->sql), "CALL SP_Get_Duobao_win_Record(%d)", nUserID);
	DataBaseReadThreadPool::instance()->pushQueue( req );
	
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////
void HttpHandler::OnHttpModifyGold( DWORD uid, INT64 gold, int diamond, int deposit,int email_type,  BYTE  moudle_type )
{
	//printf( "zq =========OnHttpModifyGold============\r\n" );
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_UPDATE_GOLD, this );
	req->id = uid;
	memset( req->sql, 0, sizeof(req->sql) );
	DBUpdateGold *pUpdateGold = (DBUpdateGold*)req->sql;
	pUpdateGold->userid = uid;
	pUpdateGold->gold = gold;
	pUpdateGold->diamond = diamond;
	pUpdateGold->deposit = deposit;
	pUpdateGold->emailtype = email_type;
	pUpdateGold->moduletype = moudle_type;
	DataBaseReadThreadPool::instance()->pushQueue( req );
}	


void HttpHandler::OnDBModyfyGold(SQLResp * resp)
{

	DBUpdateGold * pMsg = (DBUpdateGold*)resp->data;
	int result = 0;
	if ( (resp->result == 1) && (pMsg->result == 0) )
	{
		result = 1;
	}
	
	char content [ 250 ] = { 0 };
	char str_response [ 120 ] = { 0 };

	StreamWriter stream_writer( content );
	snprintf( str_response , sizeof(str_response) ,"{\"status\":%d}", result ) ;
	stream_writer.appand( str_response );
	stream_writer.add_byte('\0');

	char str_content_len [ 20 ] = { 0 };
	snprintf( str_content_len , sizeof(str_content_len) ,"%d", stream_writer.get_buffer_len()) ;

	StreamWriter writer( m_buffer );
	writer.appand("HTTP/1.1 200 OK\r\n");
	writer.appand("Content-Length: ");
	writer.appand( str_content_len );
	writer.appand( "\r\n", 2 );
	writer.appand("Connection: close\r\n\r\n");
	writer.appand( content , stream_writer.get_buffer_len() );
	safe_send( writer.get_buffer() , writer.get_buffer_len() );
	shutdown( get_handle() , SHUT_RDWR );


	if ( result )
	{
		FrontClientHandler * handler = ActiveConnsList::instance()->find( pMsg->userid );
		//printf( "zq OnDBModyfyGold handler=%x \r\n", handler );
		if ( handler && handler->getPlayer()  )
		{
			Player * player = handler->getPlayer() ;
			player->set_user_gold( player->get_user_gold() + pMsg->gold);
			player->set_diamond( player->get_diamond() + pMsg->diamond );
			player->setdepositgold( player->getdepositgold() + pMsg->deposit );
			//发送邮件
			char senddata[256] = {0};
			char tipsstr[128] = {0};
			const char *contentformat ;
			if ( ((pMsg->gold + pMsg->deposit) != 0)  && (pMsg->diamond != 0) )
			{
				contentformat = Config::instance()->get_horn_format( HORN_FORMAT_GIVEGOLDDIAMOND );
				sprintf( tipsstr, (char*)contentformat,  pMsg->gold + pMsg->deposit, pMsg->diamond );
			}
			else if ( (pMsg->gold + pMsg->deposit) != 0 )
			{
				if(pMsg->emailtype == EMAIL_TYPE_LIANGHAO)
				{
					contentformat = Config::instance()->get_horn_format( HORN_FORMAT_LIANGHAO );
				}
				else
				{
					contentformat = Config::instance()->get_horn_format( HORN_FORMAT_GIVEGOLD );
				}
				sprintf( tipsstr, (char*)contentformat,  pMsg->gold + pMsg->deposit );
			}
			else if ( pMsg->diamond != 0 )
			{
				contentformat = Config::instance()->get_horn_format( HORN_FORMAT_GIVEDIAMOND );
				sprintf( tipsstr, (char*)contentformat,  pMsg->diamond );
			}
			else
			{
				return ;
			}
			
			//CsvDataMgr::instance()->gb2312toutf8((char *)tipsstr, strlen(tipsstr), utf8tipsstr, sizeof(utf8tipsstr));
			StreamWriter mail_stream_out(senddata, sizeof(senddata));
			mail_stream_out.add_byte( pMsg->emailtype);
			int msglen = strlen(tipsstr);
			mail_stream_out.add_short(msglen);
			mail_stream_out.appand(tipsstr, msglen);
			handler->sendPacket(MSG_NOTIFY_ADD_EMAIL, senddata, mail_stream_out.get_buffer_len());
			//handler->AddMail();
			//通知给桌上上的人用户金币发生改变
			StreamPacketBuilder::instance()->notifyUpdatePlayerGold( player->getTable() , player ) ;; //通知更新金币
		}
	}
	
}


void HttpHandler::OnHttpResetPwd( char* phone, char* pwd, int type )
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_HTTP_RESET_PWD, this );
	req->id = 0;
	memset( req->sql, 0, sizeof(req->sql) );
	snprintf( req->sql , sizeof(req->sql) ,"UPDATE user_info SET user_pwd = '%s'  WHERE user_name = '%s'", pwd, phone );
	
	//printf( "zq OnHttpResetPwd sql : %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}

void HttpHandler::OnDBResult(SQLResp * resp)
{
	//printf( "zq OnDBResult resp->result = %d\r\n", resp->result );
	if ( !resp->result )
	{
		response_faild( 0, NULL );
		return;
	}
	response_sucessful(NULL);
}


void HttpHandler::OnHttpUpdateHeaderPic( DWORD uid, char* pic )
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_UPDATE_HEADER_PIC, NULL );
	req->id = 0;
	memset( req->sql, 0, sizeof(req->sql) );
	snprintf( req->sql , sizeof(req->sql) ,"UPDATE user_info SET head_picture = '%s'  WHERE user_id = %d ", pic, uid );

	//printf( "zq OnHttpUpdateHeaderPic sql : %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );

	response_sucessful(NULL);

	//查找用户
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( uid );
	if ( pClientHandle )
	{
		Player *pPlayer = pClientHandle->getPlayer();
		if ( !pPlayer )
		{
			return;
		}
		pPlayer->getUserInfo().set_head_picture( pic );
	}
	
}




void HttpHandler::OnHttpUpdateCongif( RELOAD_CONFIG_TYPE index )
{
	bool isnotifygs = false;
	//printf( "tt rec http msg index=%d \r\n", index );
	Config::instance()->opendb();
	switch ( index )
	{
	case RELOAD_CONFIG_TIGER:
		Config::instance()->load_tiger_configure();
		break;
	case RELOAD_CONFIG_MALL:
		Config::instance()->load_mall_goods_configure();
		break;
	case RELOAD_CONFIG_LOTTERY:
		Config::instance()->load_lottery_configure();
		break;
	case RELOAD_CONFIG_GOODCARDS:
		Config::instance()->load_room_control_card_conf();
		isnotifygs = true;
		break;
	case  RELOAD_CONFIG_BANKUPTCY:
		Config::instance()->load_game_config();
		isnotifygs = true;
		break;
	case RELOAD_CONFIG_ONLINEBOX:
		Config::instance()->load_online_reward_conf();
		isnotifygs = true;
		break;
	case RELOAD_CONFIG_SIGN:
		Config::instance()->load_sign_in_data();
		break;
	case RELOAD_CONFIG_HORN:
		Config::instance()->load_send_horn_min_gold_conf();
		break;
	case RELOAD_CONFIG_TASK:
		Config::instance()->load_task_config();
		break;
	case RELOAD_CONFIG_HONGBAO:
		Config::instance()->load_hongbao_task_config();
		break;
	case RELOAD_CONFIG_LOTTERYDRAW:
		Config::instance()->load_lotterydraw_config();	
		break;
	case RELOAD_CONFIG_BRC:
		{
			Config::instance()->load_brc_base_config();
			Config::instance()->load_brc_wld_config();
			CBrcMsgHandle::instance()->PushBrcConfigToBrcSvr();
		}
		break;
	case RELOAD_CONFIG_SHISHICAI:
		Config::instance()->load_shishicai_config();
		GameLotteryNew::instance()->updateLotteryCtrlGold();
		break;
	}
	Config::instance()->closedb();
	response_sucessful(NULL);

}

//商品出售/购买  index: 1出售 2购买
void HttpHandler::OnHttpBuyPlayerGoods( int index, int selluserid, int buyuserid, string emailcontent )
{
	response_sucessful(NULL);
	//查找用户
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( selluserid );
	if ( pClientHandle )
	{
		//保存到数据库
		SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_USER_SELL_BUY_GOODS, pClientHandle );
		req->id = selluserid;
		memset( req->sql, 0, sizeof(req->sql) );
		DB_BUY_SELLGOODS_DATA* pMsg = (DB_BUY_SELLGOODS_DATA*)req->sql;
		pMsg->userid = pClientHandle->getPlayer()->get_user_id();
		pMsg->type = index;
		if ( index == 2 )
		{
			snprintf( pMsg->emailcontent, sizeof(pMsg->emailcontent) - 1, "%s", emailcontent.c_str() ) ;
		}
		else
		{
			StreamPacketBuilder::instance()->notifySystemBroadcast( (u8_t*)emailcontent.c_str(), emailcontent.length() ,selluserid);
		}
		DataBaseReadThreadPool::instance()->pushQueue( req );
	}
	if ( index == 2 )
	{
		pClientHandle = ActiveConnsList::instance()->find( buyuserid );
		if ( pClientHandle )
		{
			//保存到数据库
			SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_USER_SELL_BUY_GOODS, pClientHandle );
			req->id = buyuserid;
			memset( req->sql, 0, sizeof(req->sql) );
			DB_BUY_SELLGOODS_DATA* pMsg = (DB_BUY_SELLGOODS_DATA*)req->sql;
			pMsg->userid = pClientHandle->getPlayer()->get_user_id();
			pMsg->type = index;
			//printf( "zq OnHttpBuyPlayerGoods sql : %s\r\n", req->sql );
			DataBaseReadThreadPool::instance()->pushQueue( req );
			
		}
	}
}


void HttpHandler::OnHttpUpdateWealth( int userid, char* msg )
{
	response_sucessful(NULL);
	//查找用户
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( userid );
	if ( !pClientHandle || !pClientHandle->getPlayer() )
	{
		//printf( "zq OnHttpUpdateWealth userid = %d offline\r\n", userid );
		return;
	}
	//保存到数据库
	SQLReq * req = SQLMemoryPool::instance()->mallocReq( REQ_TYPE_GET_USER_WEALTH_EX, pClientHandle );
	req->id = pClientHandle->getPlayer()->get_user_id();
	snprintf( req->sql , sizeof(req->sql) , "SELECT gold, diamond, ticket, \'%s\' AS \'message\' FROM user_info WHERE user_id = %u;", msg, pClientHandle->getPlayer()->get_user_id() );
	//printf( "zq OnHttpUpdateWealth sql : %s\r\n", req->sql );
	DataBaseReadThreadPool::instance()->pushQueue( req );
}


void HttpHandler::OnHttpKickPlayer( int userid )
{
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( userid );
	//printf( "entry OnHttpKickPlayer... pClientHandle = %x  userid = %d\r\n", pClientHandle, userid );
	if ( pClientHandle )
	{
		//printf( "is onlien\r\n" );
		pClientHandle->sendPacket( MSG_NOTIFY_KICK_GAME, NULL, 0 );
		if ( pClientHandle->getPlayer() )
		{
			//printf( "player is normal\r\n" );
			if ( pClientHandle->getPlayer()->getTable() )
			{
				//printf( "player in table\r\n" );
				pClientHandle->getPlayer()->getTable()->leaveTable( pClientHandle->getPlayer() ); 
			}
			if ( !pClientHandle->isClosed() )
			{
				//printf( "player no close\r\n" );
				pClientHandle->close(); //把socket关了
				CloseConnsList::instance()->add( pClientHandle );
				ActiveConnsList::instance()->remove( pClientHandle->getPlayer()->get_user_id() );
			}
		}
	}
	response_sucessful(NULL);
}


void HttpHandler::OnHttpUpdateVepLevel(int userid, int viplevel , int vippoint, int cardtype, int cardnum)
{
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( userid );
	if ( pClientHandle && pClientHandle->getPlayer() )
	{
		pClientHandle->getPlayer()->set_vip_level( viplevel );
		//StreamPacketBuilder::instance()->notifyUpdatePlayerGold( pClientHandle->getPlayer()->getTable() , pClientHandle->getPlayer() ) ;; //通知更新财产信息
		char senddata[128] = {0};
		StreamWriter stream_out(senddata, sizeof(senddata));
		stream_out.add_byte( viplevel );
		stream_out.add_byte( cardtype );
		stream_out.add_byte( cardnum );
		stream_out.add_int( vippoint );
		pClientHandle->sendPacket(MSG_NOTIFY_UPDATE_VIP, stream_out.get_buffer(), stream_out.get_buffer_len());
	}
	response_sucessful(NULL);
}

void HttpHandler::OnHttpUdateGift(int userid,int giftid,int giftnum,int ticket, string content)
{
	SQLReq * req = SQLMemoryPool::instance()->mallocReq(REQ_TYPE_UPDATE_GIFT_CNT, this );
	req->id = userid;
	memset( req->sql, 0, sizeof(req->sql) );
	DBUpdateGift *pUpdateGift = (DBUpdateGift*)req->sql;
	pUpdateGift->userid = userid;
	pUpdateGift->giftid= giftid;
	pUpdateGift->giftnum= giftnum;
	pUpdateGift->ticket= ticket;
	memcpy(pUpdateGift->content, content.c_str(), sizeof(pUpdateGift->content));
	DataBaseReadThreadPool::instance()->pushQueue( req );

	response_sucessful(NULL);
}


void HttpHandler::OnDBModifyGift(SQLResp * resp)
{
	DBUpdateGift* pMsg = (DBUpdateGift*)resp->data;
	int result = 0;
	printf("resp->result ==%d \n", resp->result);
	
	if ( (resp->result == 1) && (pMsg->result == 0) )
	{
		result = 1;
	}

	if ( result)
	{
		int nUserID = pMsg->userid;
		FrontClientHandler *pHandle = ActiveConnsList::instance()->find(nUserID);
		if(pHandle == NULL || (pHandle->getPlayer() == NULL))
		{
			return;
		}
		pHandle->getPlayer()->SetGiftCount(pMsg->giftid, pMsg->giftnum);
		pHandle->getPlayer()->set_user_ticket(pMsg->ticket);

		char msgdata[1024] ={0};
		StreamWriter stream_out(msgdata, sizeof(msgdata));
		stream_out.add_byte( result );
		stream_out.add_uint( pHandle->getPlayer()->getUserInfo().flower );
		stream_out.add_uint( pHandle->getPlayer()->getUserInfo().aggs );
		stream_out.add_uint( pHandle->getPlayer()->getUserInfo().car );
		stream_out.add_uint( pHandle->getPlayer()->getUserInfo().villa );
		stream_out.add_uint( pHandle->getPlayer()->getUserInfo().yacht );
		stream_out.add_uint(pHandle->getPlayer()->getUserInfo().user_score.ticket);
		
		pHandle->sendPacket( MSG_RESP_SIS_GIVE_GIFT, stream_out.get_buffer(), stream_out.get_buffer_len() );


		//send mail
		char senddata[1024] ={0};
		StreamWriter mail_stream_out(senddata, sizeof(senddata));
		mail_stream_out.add_byte(EMAIL_TYPE_GIFT);
		int msglen = strlen(pMsg->content);
		mail_stream_out.add_short(msglen);
		mail_stream_out.appand(pMsg->content, msglen);
		pHandle->sendPacket(MSG_NOTIFY_ADD_EMAIL, senddata, mail_stream_out.get_buffer_len());
		printf("OnDBModifyGift  nUSerID:%d gitid:%d num:%d  feiji:%d house:%d  \n", pMsg->userid, pMsg->giftid, pMsg->giftnum, pHandle->getPlayer()->getUserInfo().yacht,
			pHandle->getPlayer()->getUserInfo().villa);

		return ;
	}

	WL(LL_INFO, "resp->result:%d   pMsg->result:%d \n", resp->result, pMsg->result);
}


void HttpHandler::OnHttpUpdateTexiao(int nUserID)
{
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( nUserID );
	if ( pClientHandle && pClientHandle->getPlayer() )
	{
		pClientHandle->getPlayer()->set_texiao(1);
	}
	response_sucessful(NULL);
}

void HttpHandler::OnHttpUserEmailNotify(int nUserID,string emailStr, int nEmailType)
{
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( nUserID );
	if(pClientHandle)
	{
		char senddata[1024] ={0};
		StreamWriter mail_stream_out(senddata, sizeof(senddata));
		mail_stream_out.add_byte(EMAIL_TYPE_MAX);
		int msglen = emailStr.length();
		mail_stream_out.add_short(msglen);
		mail_stream_out.appand(emailStr.c_str(), msglen);
		pClientHandle->sendPacket(MSG_NOTIFY_ADD_EMAIL, senddata, mail_stream_out.get_buffer_len());
	}

	response_sucessful(NULL);
}

void HttpHandler::OnHttpWinningDuobaoNotify(int nUserID,string strContent)
{
	FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( nUserID );
	if(pClientHandle)
	{
		char senddata[2048] ={0};
		StreamWriter mail_stream_out(senddata, sizeof(senddata));
		int msglen = strContent.length();
		mail_stream_out.add_short(msglen);
		mail_stream_out.appand(strContent.c_str(), msglen);
		pClientHandle->sendPacket(MSG_NOTIFY_DUOBAO, senddata, mail_stream_out.get_buffer_len());


		SQLReq *req = SQLMemoryPool::instance()->mallocReq();
		snprintf(req->sql, sizeof(req->sql), "Update duobao_win_record SET isread = 1 where uid=%d AND isread = 0", nUserID);
		DataBaseCommitThread::instance()->push( req );
	}

	response_sucessful(NULL);
}


void HttpHandler::OnHttpPushNotify(int notify_type, string &title, string &content , string &plist)
{
	response_sucessful(NULL);

	char senddata[2048] ={0};
	StreamWriter stream_out(senddata, sizeof(senddata));
	int title_len = title.length();
	int content_len = content.length();
	stream_out.add_uint(title_len);
	stream_out.appand(title.c_str(), title_len);
	stream_out.add_uint(content_len);
	stream_out.appand(content.c_str(), content_len);

	std::vector<int> player_list;
	if ( notify_type == 1 ) //broadcast all server
	{
		StreamPacketBuilder::instance()->handleBroadcast(MSG_PUSH_CONTENT_NOTIFY,(u8_t*)stream_out.get_buffer(), stream_out.get_buffer_len());
		return;
	}

	else if ( notify_type == 0  && plist.c_str() != NULL)
	{
		 const  char *delims = ",";
		 char *result = NULL;
		 result = ::strtok((char*)plist.c_str(), delims );
		 while( result != NULL )
		 {	
			player_list.push_back(::atoi(result));
			result = strtok( NULL, delims );
		 }
	}

	BYTE email_type = EMAIL_TYPE_PUSH; 
	int nSize = player_list.size();
	for(int idx = 0; idx < nSize; idx++)
	{
		int nUserID = player_list[idx];
		FrontClientHandler *pClientHandle = ActiveConnsList::instance()->find( nUserID );
		if(pClientHandle == NULL)
		{
			SQLReq *req_email = SQLMemoryPool::instance()->mallocReq();
			snprintf(req_email->sql, sizeof(req_email->sql), "CALL p_email_add(%d,'%s', %d)", nUserID,content.c_str(), email_type);
			DataBaseCommitThread::instance()->push( req_email );
			continue;
		}
		pClientHandle->sendPacket(MSG_PUSH_CONTENT_NOTIFY, senddata, stream_out.get_buffer_len());
	}
}
